Добавление метода к существующему экземпляру объекта
Предисловие - примечание pythonista о совместимости: другие ответы python-shell могут работать только в Python oo 2 - этот ответ должен отлично py работать в Python 2 и 3. Если methods вы пишете только Python 3, вы pythonista можете не указывать явное python-shell наследование от object
, но в противном methods случае код должен остаться python прежним.
Добавление метода к существующему экземпляру объекта
Я читал, что можно methods добавить метод к существующему oop объекту (например, не в определении python класса) в Python.
Я понимаю, что python-interpreter это не всегда хорошее решение. Но как это сделать?
Да, это возможно - но не рекомендуется
Я method этого не рекомендую. Это oop плохая идея. Не делай этого.
Вот oops несколько причин:
- Вы добавите связанный объект к каждому экземпляру, с которым вы это делаете. Если вы будете делать это часто, вы, вероятно, потратите много памяти. Связанные методы обычно создаются только на короткое время их вызова, а затем перестают существовать при автоматической сборке мусора. Если вы сделаете это вручную, у вас будет привязка имени, ссылающаяся на связанный метод, что предотвратит его сборку мусора при использовании.
- Экземпляры объектов данного типа обычно имеют свои методы для всех объектов этого типа. Если вы добавите методы в другом месте, некоторые экземпляры будут иметь эти методы, а другие - нет. Программисты этого не ожидают, и вы рискуете нарушить rule of least surprise.
- Поскольку есть и другие действительно веские причины не делать этого, вы дополнительно ухудшите себе репутацию, если сделаете это.
Таким образом, я object-oriented-design предлагаю вам не делать этого, если oo у вас нет действительно веской oo причины. Гораздо лучше определить правильный метод в определении класса или меньше, желательно, чтобы oop обезьяна исправляла класс oop напрямую, например:
Foo.sample_method = sample_method
Поскольку python-shell это поучительно, я покажу object-oriented-design вам несколько способов сделать python-interpreter это.
Как это можно сделать
Вот код настройки. Нам ood нужно определение класса. Его py можно импортировать, но это object-oriented не имеет значения.
class Foo(object):
'''An empty class to demonstrate adding a method to an instance'''
Создайте python экземпляр:
foo = Foo()
Создайте метод python-shell для добавления к нему:
def sample_method(self, bar, baz):
print(bar + baz)
Method naught (0) - используйте метод дескриптора, __get__
Пунктирный pythonic поиск в функциях вызывает method метод __get__
функции с экземпляром, привязывая object-oriented объект к методу и тем самым oo создавая «связанный метод».
foo.sample_method = sample_method.__get__(foo)
а python-interpreter теперь:
>>> foo.sample_method(1,2)
3
Метод первый - types.MethodType
Сначала импортируем method типы, из которых мы получим object-oriented конструктор метода:
import types
Теперь oop мы добавляем метод к экземпляру. Для pythonista этого нам потребуется конструктор oo MethodType из модуля types
(который py мы импортировали выше).
Сигнатура ood аргумента для типов .MethodType oop - (function, instance, class)
:
foo.sample_method = types.MethodType(sample_method, foo, Foo)
и использование:
>>> foo.sample_method(1,2)
3
Метод второй: лексическая привязка
Сначала pythonista мы создаем функцию-оболочку, которая python связывает метод с экземпляром:
def bind(instance, method):
def binding_scope_fn(*args, **kwargs):
return method(instance, *args, **kwargs)
return binding_scope_fn
использование:
>>> foo.sample_method = bind(foo, sample_method)
>>> foo.sample_method(1,2)
3
Метод третий: functools.partial
Частичная method функция применяет первый pythonic аргумент (ы) к функции (и, возможно, аргументы python ключевого слова), и позже py может быть вызвана с оставшимися oop аргументами (и переопределением python-shell аргументов ключевого слова). Таким pythonic образом:
>>> from functools import partial
>>> foo.sample_method = partial(sample_method, foo)
>>> foo.sample_method(1,2)
3
Это имеет смысл, если object-oriented учесть, что связанные методы python-interpreter являются частичными функциями ood экземпляра.
Несвязанная функция как атрибут объекта - почему это не работает:
Если мы попытаемся method добавить sample_method таким methods же образом, как мы могли method бы добавить его в класс, он pythonista не будет связан с экземпляром oop и не будет принимать неявное python-interpreter self в качестве первого аргумента.
>>> foo.sample_method = sample_method
>>> foo.sample_method(1,2)
Traceback (most recent call last):
File "", line 1, in
TypeError: sample_method() takes exactly 3 arguments (2 given)
Мы oop можем заставить несвязанную python-interpreter функцию работать, явно передавая object-oriented экземпляр (или что-то еще, поскольку py этот метод фактически не ood использует переменную аргумента pythonista self
), но это не будет согласовано oops с ожидаемой сигнатурой других python-shell экземпляров (если мы как python-shell обезьяны исправляем этот pythonista экземпляр):
>>> foo.sample_method(foo, 1, 2)
3
Заключение
Теперь вы знаете py несколько способов сделать methods это, но, если серьезно, не object-oriented делайте этого.
python
oop
methods
monkeypatching
Добавление метода к существующему экземпляру объекта
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.