Добавление метода в существующий экземпляр объекта

Для Razor поместите файл DateTime.cshtml в папку Views / Shared / EditorTemplates. DateTime.cshtml содержит две строки и создает TextBox с датой, отформатированной 9/11/2001.

@model DateTime?
@Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datePicker" })
568
задан Paul Ratazzi 22 December 2017 в 18:55
поделиться

5 ответов

В Python существует различие между функциями и связанными методами.

>>> def foo():
...     print "foo"
...
>>> class A:
...     def bar( self ):
...         print "bar"
...
>>> a = A()
>>> foo
<function foo at 0x00A98D70>
>>> a.bar
<bound method A.bar of <__main__.A instance at 0x00A9BC88>>
>>>

Связанные методы были "связаны" (как описательный) к экземпляру, и тот экземпляр будет передан как первый аргумент каждый раз, когда метод называют.

Callables, которые являются атрибутами класса (в противоположность экземпляру) все еще развязаны, тем не менее, таким образом, можно изменить определение класса каждый раз, когда Вы хотите:

>>> def fooFighters( self ):
...     print "fooFighters"
...
>>> A.fooFighters = fooFighters
>>> a2 = A()
>>> a2.fooFighters
<bound method A.fooFighters of <__main__.A instance at 0x00A9BEB8>>
>>> a2.fooFighters()
fooFighters

Ранее определенные экземпляры обновляются также (как долго, поскольку они не переопределили атрибут сами):

>>> a.fooFighters()
fooFighters

проблема возникает, когда Вы хотите присоединить метод к единственному экземпляру:

>>> def barFighters( self ):
...     print "barFighters"
...
>>> a.barFighters = barFighters
>>> a.barFighters()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: barFighters() takes exactly 1 argument (0 given)

функция автоматически не связывается, когда она присоединяется непосредственно к экземпляру:

>>> a.barFighters
<function barFighters at 0x00A98EF0>

Для привязки его мы можем использовать функция MethodType в модуле типов :

>>> import types
>>> a.barFighters = types.MethodType( barFighters, a )
>>> a.barFighters
<bound method ?.barFighters of <__main__.A instance at 0x00A9BC88>>
>>> a.barFighters()
barFighters

На этот раз другие экземпляры класса не были затронуты:

>>> a2.barFighters()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'barFighters'
[еще 1119] информация может быть найдена путем чтения [приблизительно 118] дескрипторов и программирование .

метакласса

846
ответ дан Ethan Furman 22 December 2017 в 18:55
поделиться

То, что отправил Jason Pratt, корректно.

>>> class Test(object):
...   def a(self):
...     pass
... 
>>> def b(self):
...   pass
... 
>>> Test.b = b
>>> type(b)
<type 'function'>
>>> type(Test.a)
<type 'instancemethod'>
>>> type(Test.b)
<type 'instancemethod'>

, Как Вы видите, Python не считает b () несколько отличающимся, чем (). В Python все методы являются просто переменными, которые, оказывается, функции.

3
ответ дан Acuminate 22 December 2017 в 18:55
поделиться

У обезьяны Python, исправляющей обычно, работает путем перезаписи класса или подписи функций с собственным. Ниже пример от Zope Wiki:

from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
   return "ook ook eee eee eee!"
SomeClass.speak = speak

, Что код перезапишет/создаст названный метод, говорят о классе. В Jeff Atwood недавнее сообщение на обезьяне, исправляющей . Он показывает пример в C# 3.0, который является текущим языком, который я использую для работы.

16
ответ дан Cœur 22 December 2017 в 18:55
поделиться

То, что Вы ищете, setattr, я верю. Используйте это для установки атрибута на объекте.

>>> def printme(s): print repr(s)
>>> class A: pass
>>> setattr(A,'printme',printme)
>>> a = A()
>>> a.printme() # s becomes the implicit 'self' variable
< __ main __ . A instance at 0xABCDEFG>
6
ответ дан HS. 22 December 2017 в 18:55
поделиться

Модуль новый устарел с версии python 2.6 и удален в версии 3.0, используйте типы

см. http://docs.python.org/library/new.html

В приведенном ниже примере я намеренно удалил возвращаемое значение из функции patch_me () . Я думаю, что передача возвращаемого значения может заставить поверить в то, что patch возвращает новый объект, что неверно - он изменяет входящий. Вероятно, это может способствовать более дисциплинированному использованию monkeypatching.

import types

class A(object):#but seems to work for old style objects too
    pass

def patch_me(target):
    def method(target,x):
        print "x=",x
        print "called from", target
    target.method = types.MethodType(method,target)
    #add more if needed

a = A()
print a
#out: <__main__.A object at 0x2b73ac88bfd0>  
patch_me(a)    #patch instance
a.method(5)
#out: x= 5
#out: called from <__main__.A object at 0x2b73ac88bfd0>
patch_me(A)
A.method(6)        #can patch class too
#out: x= 6
#out: called from <class '__main__.A'>
93
ответ дан 22 November 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: