Я пытаюсь сделать на 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 ()
Решение приведено ниже, но зачем вам это?
data.fn = staticmethod(myFunction)
Должен сделать свое дело.
Это правильный ответ и синтаксис, поскольку функция определена в другом месте.
Что вы можете сделать:
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?
Воспользуйтесь ссылкой редактирования вашего вопроса, чтобы добавить дополнительную информацию. Кнопка «Ответить» должна использоваться только для полных ответов на вопрос.
Я думаю, вы намеревались использовать: d.fn (1,2,3), а не d.myFunctions (1,2,3)