Хранение несвязанных функций 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 есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
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

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