хранение несвязанных функций Python в объекте класса - PullRequest
16 голосов
/ 29 ноября 2008

Я пытаюсь сделать следующее в 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: необязательный метод f () должен быть вызван с экземпляром данных в качестве первого аргумента (вместо этого получен экземпляр int)

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

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

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

Ответы [ 4 ]

24 голосов
/ 29 ноября 2008
data.fn = staticmethod(myFunction)

должен сделать трюк.

1 голос
/ 29 ноября 2008

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

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

d.fn(1,2,3)

Что может быть не совсем тем, что вы хотите, но работает.

0 голосов
/ 30 ноября 2008

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

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

В моем приложении пользователи могут писать плагины на 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 для запуска кода плагина, а затем извлекаю объект класса, упомянутый выше, - это дает мне данные конфигурации и функцию плагина, чтобы я мог запустить его без ошибок загрязняет мое пространство имен).

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

0 голосов
/ 29 ноября 2008

Это кажется бессмысленным для меня. Почему бы просто не вызвать myFunction, когда вам это нужно?

В общем, в Python мы используем модули для этого типа пространства имен (в отличие от Java, где у вас просто нет выбора). И, конечно же, myFunction уже связана с пространством имен модуля, когда вы его определяете.

Это несколько обсуждается в ответах на этот вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...