Методы расширения в Python - PullRequest
       38

Методы расширения в Python

41 голосов
/ 05 февраля 2009

Есть ли в Python методы расширения, такие как C #? Можно ли вызвать метод, подобный:

MyRandomMethod()

для существующих типов, таких как int?

myInt.MyRandomMethod()

Ответы [ 5 ]

51 голосов
/ 05 февраля 2009

Вы можете добавить любые методы, которые вам нравятся, к объектам класса, определенным в коде Python (AKA monkey patching):

>>> class A(object):
>>>     pass


>>> def stuff(self):
>>>     print self

>>> A.test = stuff
>>> A().test()

Это не работает со встроенными типами, потому что их __dict__ недоступно для записи (это dictproxy).

Так что нет, в Python нет «реального» механизма метода расширения.

9 голосов
/ 05 февраля 2009

не уверен, что это то, что вы спрашиваете, но вы можете расширить существующие типы, а затем вызывать что угодно на новой вещи:

class  int(int):
     def random_method(self):
           return 4                     # guaranteed to be random
v = int(5)                              # you'll have to instantiate all you variables like this
v.random_method()

class int(int):
    def xkcd(self):
        import antigravity
        print(42)

>>>v.xkcd()
Traceback (most recent call last):
  File "<pyshell#81>", line 1, in <module>
    v.xkcd()
AttributeError: 'int' object has no attribute 'xkcd'
c = int(1)
>>> c.random_method()
4
>>> c.xkcd()
42

надеюсь, что прояснит ваш вопрос

4 голосов
/ 07 мая 2018

Это можно сделать с Запретным Фруктом (https://pypi.python.org/pypi/forbiddenfruit)

Установить запрещенный фрукт:

pip install forbiddenfruit

Затем вы можете расширить встроенные типы:

>>> from forbiddenfruit import curse

>>> def percent(self, delta):
...     return self * (1 + delta / 100)

>>> curse(float, 'percent', percent)
>>> 1.0.percent(5)
1.05

Forbidden Fruit в основном зависит от C API, он работает только с реализациями cpython и не будет работать с другими реализациями Python, такими как Jython, pypy и т. Д.

1 голос
/ 05 февраля 2009

Мне очень повезло с методом, описанным здесь:

http://mail.python.org/pipermail/python-dev/2008-January/076194.html

Я понятия не имею, работает ли он на встроенных функциях.

0 голосов
/ 05 февраля 2009

Другой вариант - переопределить мета-класс. Это позволяет, помимо прочего, указывать функции, которые должны существовать во всех классах.

Эта статья начинает обсуждать это:

http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html

...