Varolan nesne örneği için bir Yöntem Ekleme

oy
488

Ben Python varolan nesne (yani değil sınıf tanımında) için bir yöntem eklemek mümkün olduğunu okudum.

Ben bunu yapmak için her zaman iyi olmadığını anlıyoruz. Ama nasıl kimse bu yapabiliriz?

Oluştur 04/08/2008 saat 03:17
kaynak kullanıcı
Diğer dillerde...                            


18 cevaplar

oy
736

Python'da, fonksiyonları ve sınır yöntemler arasında bir fark yoktur.

>>> 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>>
>>>

Bağlanmış yöntemleri (kadar açıklayıcı) örneğine "bağlı" olmuştur ve bu örnek yöntemi çağrıldığında ilk bağımsız değişken olarak geçirilir.

(Örneğine karşılık) bir sınıfın nitelikleridir istediğiniz zaman sınıf tanımını değiştirebilir böylece olsa da, hala ilişkisiz olan 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

Daha önce tanımlanmış örnekleri (yeter ki Özellik kendilerini geçersiz değil gibi) yanı güncellenir:

>>> a.fooFighters()
fooFighters

Tek bir örneğine bir yöntem eklemek istediğinizde sorun gelir:

>>> 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)

bir örneğine doğrudan bağlı olduğu fonksiyon otomatik olarak bağlı değildir:

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

Bağlamak için, kullanabileceğimiz türleri modülünde MethodType işlevi :

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

sınıfın Bu kez diğer örnekleri etkilenmediğini:

>>> a2.barFighters()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'barFighters'

Daha fazla bilgi hakkında okuyarak bulunabilir tanımlayıcıları ve metaclass programlama .

Cevap 06/08/2008 saat 01:33
kaynak kullanıcı

oy
80

Modül yeni piton 2.6 yana kaldırıldı ve 3.0, kullanım uzaklaştırılır türleri

bkz http://docs.python.org/library/new.html

Örnekte ben kasten dönüş değeri kaldırdık aşağıda patch_me()fonksiyonu. O Gelen birini değiştirir - Ben dönüş değerini vererek bir yama doğru değildir yeni bir nesne döndürür inandırmaya olabileceğini düşünüyorum. Muhtemelen bu monkeypatching daha disiplinli kullanımını kolaylaştırabilir.

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'>
Cevap 06/06/2009 saat 06:31
kaynak kullanıcı

oy
47

Varolan nesne örneği için bir Yöntem Ekleme

Python içinde (örneğin değil sınıf tanımında) mevcut bir nesneye bir yöntem eklemek mümkün olduğunu okudum.

Tabii hep bunu yapmak için iyi bir karar olmadığını anlıyoruz. Ama, kimse bu nasıl yapacağım?

Evet, bu mümkün - Ama önerilmez

Bunu önermiyoruz. Bu kötü bir fikir. Yapmayın.

İşte birkaç nedeni var:

  • Sen bunu her örneği için bağlı nesne ekleyeceğiz. Bunun bir çok yaparsanız, muhtemelen çok fazla bellek atık edeceğiz. Bağımlı yöntemler genellikle sadece onların aramanın kısa bir süre için oluşturulur ve bunlar daha sonra otomatik çöp toplama geçerliliğini kaybeder. kullanım üzerindeki çöp toplama engelleyecektir - elle bu yaparsanız, bağımlı yöntemi başvuran bağlayıcı bir isim olacak.
  • Belirli bir türden nesne örnekleri genellikle bu türdeki tüm nesneler üzerindeki yöntemleri var. Başka bir yerde yöntemleri eklerseniz, bazı durumlarda bu yöntemleri sahip olacak ve bazıları edilmez. Programcılar bu beklemeyin, siz ihlal riske az sürpriz üstünlüğü .
  • Bunu yapmak için değil, diğer gerçekten iyi nedenler vardır beri bunu yaparsanız, ayrıca kendine bir kötü üne vereceğiz.

Böylece, sana gerçekten iyi bir nedeniniz olmadıkça bunu yapamazsın düşündürmektedir. Sınıf tanımında doğru yöntemi tanımlamak için çok daha iyi ya da daha az , bu gibi sınıf doğrudan tercihen maymun yama:

Foo.sample_method = sample_method

o öğretici olduğu için, ancak, sana bunu yapmanın bazı yolları göstermek için gidiyorum.

bu yapılabilir nasıl

İşte bazı kurulum şifresi. Bir sınıf tanımını gerekir. Bu ithal edilebilir, ama gerçekten önemli değil.

class Foo(object):
    '''An empty class to demonstrate adding a method to an instance'''

bir örneğini oluşturun:

foo = Foo()

buna eklemek için bir yöntem oluşturun:

def sample_method(self, bar, baz):
    print(bar + baz)

Yöntem sıfır (0) -, tanımlayıcı yöntemi kullanmak __get__

Işlevleri noktalı aramaları çağrı __get__yönteme nesne bağlama ve böylece oluşturma, örneği ile fonksiyon yöntemi "bağımlı yöntemi."

foo.sample_method = sample_method.__get__(foo)

ve şimdi:

>>> foo.sample_method(1,2)
3

Birinci yöntem - types.MethodType

Birincisi, ithalat tipleri, hangi biz yöntemi yapıcısı alırsınız:

import types

Şimdi örneğine yöntemi ekleyin. Bunu yapmak için, biz den MethodType yapıcı gerektiren types(yukarıda ithal) modülü.

Types.MethodType için argüman imzadır (function, instance, class):

foo.sample_method = types.MethodType(sample_method, foo, Foo)

ve kullanımı:

>>> foo.sample_method(1,2)
3

Yöntem: bağlayıcı sözcük

İlk olarak, örneğin yöntemi bağlanan bir sargı işlev oluşturmak:

def bind(instance, method):
    def binding_scope_fn(*args, **kwargs): 
        return method(instance, *args, **kwargs)
    return binding_scope_fn

kullanımı:

>>> foo.sample_method = bind(foo, sample_method)    
>>> foo.sample_method(1,2)
3

Yöntem üç: functools.partial

Kısmi bir fonksiyonu bir fonksiyonu (ve isteğe bağlı olarak, anahtar kelime bağımsız değişkenler) ilk bağımsız değişken (ler) uygulanır ve daha sonra kalan argümanlar (ve geçersiz kılma anahtar bağımsız değişkenler) ile çağrılabilir. Böylece:

>>> from functools import partial
>>> foo.sample_method = partial(sample_method, foo)
>>> foo.sample_method(1,2)
3    

Eğer sınır yöntemleri örneğinin kısmi fonksiyonları göz önüne aldığımızda bu mantıklı.

Bir nesne niteliği olarak Unbound fonksiyonu - bu neden çalışmıyor:

biz sınıfa ekleyebiliriz aynı şekilde sample_method eklemeye çalışırsanız, bu örneğinden ilişkisiz olduğunu ve ilk argüman olarak örtülü kendini almaz.

>>> foo.sample_method = sample_method
>>> foo.sample_method(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sample_method() takes exactly 3 arguments (2 given)

Biz (bu yöntem aslında kullanmaz çünkü ya da bir şey açıkça örneğini geçirerek bağlanmamış fonksiyon çalışmalarını yapabilir selfbiz maymun yama iseniz (argüman değişkeni), ancak diğer durumlarda beklenen imzası ile tutarlı olmaz Bu örnek):

>>> foo.sample_method(foo, 1, 2)
3

Sonuç

Artık birkaç yol biliyor olabilir bunu ancak bütün ciddiyetiyle - bunu yapmayın.

Cevap 21/01/2015 saat 05:31
kaynak kullanıcı

oy
30

Yukarıdaki cevaplar kilit noktası cevapsız düşünüyorum.

en bir yöntemle bir sınıf atalım:

class A(object):
    def m(self):
        pass

Şimdi, ipython onunla oynamasına izin:

In [2]: A.m
Out[2]: <unbound method A.m>

Ok, m (), bir şekilde bir ilişkisiz bir yöntem haline bir . Ama gerçekte böyle mi?

In [5]: A.__dict__['m']
Out[5]: <function m at 0xa66b8b4>

O çıkıyor m () sadece bir işlev, referans eklenir etmek hangi bir sihirli yoktur - sınıf sözlükte. O zaman neden Am bize bir ilişkisiz yöntem verir? Nokta basit bir sözlük arama için çevrilmez da ondan. Bu fiili bir .__ sınıf __.__ getAttribute __ bir çağrı (A, 'm') var:

In [11]: class MetaA(type):
   ....:     def __getattribute__(self, attr_name):
   ....:         print str(self), '-', attr_name

In [12]: class A(object):
   ....:     __metaclass__ = MetaA

In [23]: A.m
<class '__main__.A'> - m
<class '__main__.A'> - m

Şimdi, son satırı iki kez basılır neden kafamın üstüne dışına emin değilim, ama yine de orada neler olduğunu net.

Şimdi, varsayılan __getattribute__ yapar nitelik sözde ise o kontrol eder olmasıdır açıklayıcısı özel bir __get__ yöntemini uygulaması halinde ya da değil, yani. O yöntemi uygularsa, o zaman ne döndürülen __get__ yöntemini çağırarak sonucudur. Bizim ilk sürüme dönecek olursak bir sınıfta, bu bizim ne var:

In [28]: A.__dict__['m'].__get__(None, A)
Out[28]: <unbound method A.m>

Python fonksiyonları açıklayıcısı protokolünü uygulayan çünkü bir nesnenin adına denir eğer, onların __get__ yönteminde bu nesne kendilerini bağlarlar.

Ok, bu nedenle nasıl varolan bir nesneye bir yöntem eklenir? Eğer yama sınıfını sakıncası varsayarsak, bu kadar basit değil:

B.m = m

Sonra Bm , bağlantısız bir yöntem açıklayıcısı büyü sayesinde "olur".

Sadece tek bir nesne için bir yöntem eklemek istiyorsanız, o zaman types.MethodType kullanarak, makine kendini taklit vardır:

b.m = types.MethodType(m, b)

Bu arada:

In [2]: A.m
Out[2]: <unbound method A.m>

In [59]: type(A.m)
Out[59]: <type 'instancemethod'>

In [60]: type(b.m)
Out[60]: <type 'instancemethod'>

In [61]: types.MethodType
Out[61]: <type 'instancemethod'>
Cevap 22/01/2012 saat 15:20
kaynak kullanıcı

oy
16

Python maymun yama genellikle kendi ile sınıf veya işlevler imza üzerine yazarak çalışır. Aşağıda bir örnek Zope Wiki :

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

Bu kod sınıfı konuşmak adlı bir yöntem oluşturmak / üzerine yazılır. Jeff Atwood ise maymun yama üzerinde son yazı . O iş için kullandığınız geçerli bir dildir C # 3.0 bir örnek gösterilmektedir.

Cevap 04/08/2008 saat 03:31
kaynak kullanıcı

oy
9

Örneğine olmadan bir yöntem eklemek için en az iki yolu vardır types.MethodType:

>>> class A:
...  def m(self):
...   print 'im m, invoked with: ', self

>>> a = A()
>>> a.m()
im m, invoked with:  <__main__.A instance at 0x973ec6c>
>>> a.m
<bound method A.m of <__main__.A instance at 0x973ec6c>>
>>> 
>>> def foo(firstargument):
...  print 'im foo, invoked with: ', firstargument

>>> foo
<function foo at 0x978548c>

1:

>>> a.foo = foo.__get__(a, A) # or foo.__get__(a, type(a))
>>> a.foo()
im foo, invoked with:  <__main__.A instance at 0x973ec6c>
>>> a.foo
<bound method A.foo of <__main__.A instance at 0x973ec6c>>

2:

>>> instancemethod = type(A.m)
>>> instancemethod
<type 'instancemethod'>
>>> a.foo2 = instancemethod(foo, a, type(a))
>>> a.foo2()
im foo, invoked with:  <__main__.A instance at 0x973ec6c>
>>> a.foo2
<bound method instance.foo of <__main__.A instance at 0x973ec6c>>

Faydalı linkler:
Veri modeli - tanımlayıcılar yürütmesini
Tanımlayıcı HowTo Rehberi - çağırma tanımlayıcıları

Cevap 26/04/2013 saat 16:47
kaynak kullanıcı

oy
7

Bir örneğine bir yöntem bağlamak için lambda kullanabilirsiniz:

def run(self):
    print self._instanceString

class A(object):
    def __init__(self):
        self._instanceString = "This is instance string"

a = A()
a.run = lambda: run(a)
a.run()

Bu örnek dizedir

Süreç çıkış kodu 0 ile tamamladı

Cevap 21/07/2014 saat 13:55
kaynak kullanıcı

oy
6

olmayan Python sürümleri için sorulan bu soruya beri burada JavaScript var:

a.methodname = function () { console.log("Yay, a new method!") }
Cevap 09/03/2012 saat 16:07
kaynak kullanıcı

oy
6

Ne aradığınız olduğunu setattrinanıyorum. Bir nesne üzerinde bir öznitelik ayarlamak için bunu kullanın.

>>> 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>
Cevap 07/08/2008 saat 12:30
kaynak kullanıcı

oy
5

Bu aslında "Jason Pratt" cevabını bir eklenti olduğunu

Jasons eserler cevap rağmen kimse bir sınıfa bir işlev eklemek istiyorsa, sadece çalışır. Ben .py kaynak kod dosyasından mevcut bir yöntem yeniden çalıştığında Benim için işe yaramadı.

Bu bir geçici çözüm bulmak için yaş için götürdü, fakat hile dönüştürmek için bir yeniden 3.rd kullanım types.FunctionType (...) zorlamak 2.nd kaynak kod dosyasından kod içe 1.st ... basit görünüyor ithal ve yeniden yöntem types.MethodType (kullanarak "Jason Pratt" önerdiği gibi şimdi devam edebilirsiniz farklı bir ad adayı 4 içinde olması gibi bir işleve bağımlı yöntem ayrıca, mevcut küresel değişkenler üzerinde geçebilir ... )

Örnek:

# this class resides inside ReloadCodeDemo.py
class A:
    def bar( self ):
        print "bar1"

    def reloadCode(self, methodName):
        ''' use this function to reload any function of class A'''
        import types
        import ReloadCodeDemo as ReloadMod # import the code as module
        reload (ReloadMod) # force a reload of the module
        myM = getattr(ReloadMod.A,methodName) #get reloaded Method
        myTempFunc = types.FunctionType(# convert the method to a simple function
                                myM.im_func.func_code, #the methods code
                                globals(), # globals to use
                                argdefs=myM.im_func.func_defaults # default values for variables if any
                                ) 
        myNewM = types.MethodType(myTempFunc,self,self.__class__) #convert the function to a method
        setattr(self,methodName,myNewM) # add the method to the function

if __name__ == '__main__':
    a = A()
    a.bar()
    # now change your code and save the file
    a.reloadCode('bar') # reloads the file
    a.bar() # now executes the reloaded code
Cevap 18/08/2015 saat 15:32
kaynak kullanıcı

oy
5

Siz gerçekten bakmak gerekir yasak meyve , o bile dizeleri HERHANGİ piton sınıfını yama maymun destek sağlayan bir piton kütüphanedir.

Cevap 25/08/2013 saat 22:56
kaynak kullanıcı

oy
5

bağlanmasının farklı yöntemlerin sonuçlarına bir bakışla, Jason Pratt ve toplum wiki cevapları birleştirme:

Özellikle bir sınıf yöntemi olarak bağlama işlevi nasıl dahil not işleri , ancak referans kapsamı yanlıştır.

#!/usr/bin/python -u
import types
import inspect

## dynamically adding methods to a unique instance of a class


# get a list of a class's method type attributes
def listattr(c):
    for m in [(n, v) for n, v in inspect.getmembers(c, inspect.ismethod) if isinstance(v,types.MethodType)]:
        print m[0], m[1]

# externally bind a function as a method of an instance of a class
def ADDMETHOD(c, method, name):
    c.__dict__[name] = types.MethodType(method, c)

class C():
    r = 10 # class attribute variable to test bound scope

    def __init__(self):
        pass

    #internally bind a function as a method of self's class -- note that this one has issues!
    def addmethod(self, method, name):
        self.__dict__[name] = types.MethodType( method, self.__class__ )

    # predfined function to compare with
    def f0(self, x):
        print 'f0\tx = %d\tr = %d' % ( x, self.r)

a = C() # created before modified instnace
b = C() # modified instnace


def f1(self, x): # bind internally
    print 'f1\tx = %d\tr = %d' % ( x, self.r )
def f2( self, x): # add to class instance's .__dict__ as method type
    print 'f2\tx = %d\tr = %d' % ( x, self.r )
def f3( self, x): # assign to class as method type
    print 'f3\tx = %d\tr = %d' % ( x, self.r )
def f4( self, x): # add to class instance's .__dict__ using a general function
    print 'f4\tx = %d\tr = %d' % ( x, self.r )


b.addmethod(f1, 'f1')
b.__dict__['f2'] = types.MethodType( f2, b)
b.f3 = types.MethodType( f3, b)
ADDMETHOD(b, f4, 'f4')


b.f0(0) # OUT: f0   x = 0   r = 10
b.f1(1) # OUT: f1   x = 1   r = 10
b.f2(2) # OUT: f2   x = 2   r = 10
b.f3(3) # OUT: f3   x = 3   r = 10
b.f4(4) # OUT: f4   x = 4   r = 10


k = 2
print 'changing b.r from {0} to {1}'.format(b.r, k)
b.r = k
print 'new b.r = {0}'.format(b.r)

b.f0(0) # OUT: f0   x = 0   r = 2
b.f1(1) # OUT: f1   x = 1   r = 10  !!!!!!!!!
b.f2(2) # OUT: f2   x = 2   r = 2
b.f3(3) # OUT: f3   x = 3   r = 2
b.f4(4) # OUT: f4   x = 4   r = 2

c = C() # created after modifying instance

# let's have a look at each instance's method type attributes
print '\nattributes of a:'
listattr(a)
# OUT:
# attributes of a:
# __init__ <bound method C.__init__ of <__main__.C instance at 0x000000000230FD88>>
# addmethod <bound method C.addmethod of <__main__.C instance at 0x000000000230FD88>>
# f0 <bound method C.f0 of <__main__.C instance at 0x000000000230FD88>>

print '\nattributes of b:'
listattr(b)
# OUT:
# attributes of b:
# __init__ <bound method C.__init__ of <__main__.C instance at 0x000000000230FE08>>
# addmethod <bound method C.addmethod of <__main__.C instance at 0x000000000230FE08>>
# f0 <bound method C.f0 of <__main__.C instance at 0x000000000230FE08>>
# f1 <bound method ?.f1 of <class __main__.C at 0x000000000237AB28>>
# f2 <bound method ?.f2 of <__main__.C instance at 0x000000000230FE08>>
# f3 <bound method ?.f3 of <__main__.C instance at 0x000000000230FE08>>
# f4 <bound method ?.f4 of <__main__.C instance at 0x000000000230FE08>>

print '\nattributes of c:'
listattr(c)
# OUT:
# attributes of c:
# __init__ <bound method C.__init__ of <__main__.C instance at 0x0000000002313108>>
# addmethod <bound method C.addmethod of <__main__.C instance at 0x0000000002313108>>
# f0 <bound method C.f0 of <__main__.C instance at 0x0000000002313108>>

bu beni dinamik hem de bir yineleyici içinde yeni yöntem isimleri atamak için izin verdiği Şahsen ben, dış ADDMETHOD fonksiyon yolu tercih ediyoruz.

def y(self, x):
    pass
d = C()
for i in range(1,5):
    ADDMETHOD(d, y, 'f%d' % i)
print '\nattributes of d:'
listattr(d)
# OUT:
# attributes of d:
# __init__ <bound method C.__init__ of <__main__.C instance at 0x0000000002303508>>
# addmethod <bound method C.addmethod of <__main__.C instance at 0x0000000002303508>>
# f0 <bound method C.f0 of <__main__.C instance at 0x0000000002303508>>
# f1 <bound method ?.y of <__main__.C instance at 0x0000000002303508>>
# f2 <bound method ?.y of <__main__.C instance at 0x0000000002303508>>
# f3 <bound method ?.y of <__main__.C instance at 0x0000000002303508>>
# f4 <bound method ?.y of <__main__.C instance at 0x0000000002303508>>
Cevap 28/01/2012 saat 01:12
kaynak kullanıcı

oy
4

Ne Jason Pratt yayınlanmıştır doğrudur.

>>> 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'>

Gördüğünüz gibi, Python) (a daha farklı) (b dikkate almaz. Tüm Python metodları fonksiyonları olarak gerçekleşmesi değişkenler sadece vardır.

Cevap 22/08/2008 saat 15:40
kaynak kullanıcı

oy
3

herhangi bir yardımcı olabilir, ben son zamanlarda daha uygun yama maymun işlemi yapmak için Gorilla adlı bir Python kütüphanesi yayınlandı.

Bir fonksiyonu kullanarak needle()adında bir modül yama guineapigaşağıdaki gibi gider:

import gorilla
import guineapig
@gorilla.patch(guineapig)
def needle():
    print("awesome")

Görüldüğü gibi Ama aynı zamanda daha ilginç kullanım durumları ilgilenir SSS gelen belgelere .

Kod mevcuttur GitHub'dan .

Cevap 15/07/2014 saat 03:12
kaynak kullanıcı

oy
2

Yukarıda listelenen yöntemlerin tüm çöp toplama kadar kalıcı olması için olan objenin, ilave yöntem ve örneği arasında bir döngü referansı oluşturan kimsenin bahsedilen garip bulmak. nesnenin sınıfını genişleterek bir tanımlayıcı ekleyerek eski bir numara vardı:

def addmethod(obj, name, func):
    klass = obj.__class__
    subclass = type(klass.__name__, (klass,), {})
    setattr(subclass, name, func)
    obj.__class__ = subclass
Cevap 30/04/2017 saat 04:57
kaynak kullanıcı

oy
2

Bu soru dekoratörler kullanarak bir sınıf örneğine bir fonksiyonun bağlanmasını taklit etmek için kolay bir yol var, hey yıl önce açılan, fakat:

def binder (function, instance):
  copy_of_function = type (function) (function.func_code, {})
  copy_of_function.__bind_to__ = instance
  def bound_function (*args, **kwargs):
    return copy_of_function (copy_of_function.__bind_to__, *args, **kwargs)
  return bound_function


class SupaClass (object):
  def __init__ (self):
    self.supaAttribute = 42


def new_method (self):
  print self.supaAttribute


supaInstance = SupaClass ()
supaInstance.supMethod = binder (new_method, supaInstance)

otherInstance = SupaClass ()
otherInstance.supaAttribute = 72
otherInstance.supMethod = binder (new_method, otherInstance)

otherInstance.supMethod ()
supaInstance.supMethod ()

Eğer bağlayıcı dekoratör fonksiyonu ve örneğini geçerken Orada, ilk olarak aynı kod nesne ile, yeni bir işlev oluşturacaktır. Sonra, sınıfın verilen örneği yeni oluşturulan fonksiyonun bir özelliği saklanır. Dekoratör ilk parametre olarak örneğini veren, otomatik olarak kopyalanır fonksiyonu çağıran bir (üçüncü) işlevini döndürür.

Sonuç olarak bunu sınıf örneğine bağlama oluyor simüle bir fonksiyon olsun. Orijinal fonksiyon değişmeden bırakmak.

Cevap 21/12/2015 saat 21:39
kaynak kullanıcı

oy
1
from types import MethodType

def method(self):
   print 'hi!'


setattr( targetObj, method.__name__, MethodType(method, targetObj, type(method)) )

Buradan hareketle, kendi kendine işaretçisi kullanabilirsiniz

Cevap 27/07/2017 saat 04:21
kaynak kullanıcı

oy
-8

Ben Python sözdizimi bilmiyorum ama Ruby yapabilir biliyorum ve oldukça önemsiz. Diyelim ki standart out uzunluğunu yazdırır Array için bir yöntem eklemek istediğinizi varsayalım:

class Array
  def print_length
    puts length
  end
end

Eğer bütün sınıfını değiştirme istemiyorsanız, sadece dizinin tek bir örneğine yöntemi ekleyebilir ve başka diziler yöntemine sahip olacaktır:

array = [1, 2, 3]
def array.print_length
  puts length
end

Sadece bu özelliği kullanarak ele alınan konuların farkında olmak. Jeff Atwood aslında bu konuda yazdığı çok uzun zaman önce.

Cevap 04/08/2008 saat 03:36
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more