Ответ 1
data.fn = staticmethod(myFunction)
должен сделать трюк.
Я пытаюсь сделать следующее в 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 метод f() должен быть вызван с экземпляром данных в качестве первого аргумента (вместо этого используется int int)
Это справедливо, я полагаю, python рассматривает метод d.myFunction как метод класса. Тем не менее, я хочу, чтобы он рассматривал его как нормальную функцию, поэтому я могу назвать это, не добавляя неиспользуемый параметр "self" в определение myFunction.
Итак, вопрос:
Как сохранить функцию в объекте класса без привязки функции к этому классу?
data.fn = staticmethod(myFunction)
должен сделать трюк.
Что вы можете сделать:
d = foo.data()
d.fn = myFunction
d.fn(1,2,3)
Это может быть не совсем то, что вы хотите, но работает.
Это кажется мне бессмысленным. Почему бы просто не позвонить myFunction, когда вам это нужно?
В общем, в Python мы используем модули для такого рода пространств имен (сравним это с Java, где у вас просто нет выбора). И, конечно, myFunction уже привязан к пространству имен модулей, когда вы его определяете.
Спасибо Андре за ответ - так просто!
Для тех из вас, кого это касается, возможно, я должен был включить весь контекст проблемы. Здесь все равно:
В моем приложении пользователи могут писать плагины в 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
для запуска кода плагина, а затем извлекаю объект класса, упомянутый выше, - это дает мне данные конфигурации и функцию плагина, поэтому я могу выполнять ее чисто (без загрязняя мое пространство имен).
Весь этот процесс повторяется несколько раз для разных плагинов на одном и том же входе и, кажется, работает очень хорошо для меня.