Хранение несвязанных функций Python в объекте класса

Я пытаюсь сделать на python следующее:

В файле с именем foo.py:

# simple function that does something:
def myFunction(a,b,c):
  print "call to myFunction:",a,b,c

# class used to store some data:
class data:
  fn = None

# assign function to the class for storage.
data.fn = myFunction

А затем в файле bar.py: import foo

d = foo.data
d.fn(1,2,3)

Однако я получаю следующую ошибку:

TypeError: unbound method f() must be called with data instance as first argument (got int instance instead)

Я полагаю, это справедливо - python рассматривает d.myFunction как метод класса. Однако я хочу, чтобы он рассматривал ее как обычную функцию, поэтому я могу вызывать ее, не добавляя неиспользуемый параметр self в определение myFunction.

Итак, вопрос:

Как я могу сохранить функцию в объекте класса без привязки функции к этому классу?

Я думаю, вы намеревались использовать: d.fn (1,2,3), а не d.myFunctions (1,2,3)

Igal Serban 29.11.2008 16:35

Да, я думаю, вы имели в виду d.fn ()

user3850 29.11.2008 16:44

Решение приведено ниже, но зачем вам это?

orip 29.11.2008 23:26
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
17
3
2 768
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
data.fn = staticmethod(myFunction)

Должен сделать свое дело.

Это правильный ответ и синтаксис, поскольку функция определена в другом месте.

tzot 29.11.2008 17:41

Что вы можете сделать:

d = foo.data()
d.fn = myFunction

d.fn(1,2,3)

Возможно, это не совсем то, что вам нужно, но действительно работает.

Спасибо Андре за ответ - так просто!

Для тех из вас, кому не все равно, возможно, мне следовало включить весь контекст проблемы. Во всяком случае, вот оно:

В моем приложении пользователи могут писать плагины на Python. Они должны определять функцию с четко определенным списком параметров, но я не хотел навязывать им какие-либо соглашения об именах.

Итак, пока пользователи пишут функцию с правильным количеством параметров и типов, все, что им нужно делать, это что-то вроде этого (помните, это код плагина):

# this is my custom code - all plugins are called with a modified sys.path, so this
# imports some magic python code that defines the functions used below.
from specialPluginHelperModule import *

# define the function that does all the work in this plugin:
def mySpecialFn(paramA, paramB, paramC):
    # do some work here with the parameters above:
    pass

# set the above function:
setPluginFunction(mySpecialFn)

Вызов setPluginFunction берет объект функции и устанавливает его в объекте скрытого класса (наряду с другими вещами, связанными с конфигурацией плагина, этот пример был несколько упрощен). Когда основное приложение хочет запустить функцию, я использую модуль runpy для запуска кода подключаемого модуля, а затем извлекаю упомянутый выше объект класса - это дает мне данные конфигурации и функцию подключаемого модуля, чтобы я мог запустить его чисто (не загрязняя свой пространство имен).

Весь этот процесс повторяется несколько раз для разных плагинов на одном и том же входе, и мне кажется, что он работает очень хорошо.

«все плагины вызываются с измененным sys.path» Вы временно изменяете sys.path в блоке try / finally или есть способ «затенять» глобальный sys.path?

haridsv 25.02.2010 22:39

Воспользуйтесь ссылкой редактирования вашего вопроса, чтобы добавить дополнительную информацию. Кнопка «Ответить» должна использоваться только для полных ответов на вопрос.

All Workers Are Essential 07.06.2016 22:02

Другие вопросы по теме