2014-07-15 20 views
5

Kalıtsal bir yöntemde bir dekoratörün nasıl kullanılacağından emin değilim. Normalde dekoratörler tanımdan önce konur, fakat miras kalan bir fonksiyon için tanım, alt sınıfta değil, çocuk sınıfında verilir. Metodun tanımını çocuk sınıfında yeniden yazmaktan kaçınmak ve dekoratörü kalıtsal yöntemin etrafına yerleştirmeyi tercih ediyorum. Çocuk sınıfında kalıtsal bir yöntemi nasıl dekore edebiliriz?

kendim daha anlaşılır kılmak için, burada ne demek istediğimi bir çalışma örneğidir:

class Person(): 
    def __init__(self, age): 
     self.age = age 

    @classmethod 
    def gets_drink(cls,): 
     print "it's time to get a drink!" 
     return "A beer" 

def dec(some_f): 
    def legal_issue(obj,): 
     some_f(obj) 
     return 'A Coke' 
    return legal_issue 

class Child(Person): 
    def __init__(self, age): 
     Person.__init__(self, age=age) 

    #in principle i'd like to write 
    #@dec 
    #self.gets_drink 
    #which does not work 
    #the only working way I found is by defining the method as a classmethod 
    #and write this: 

    @dec 
    def gets_drink(self,): 
     return Person.gets_drink() 

dad = Person(42) 
son = Child(12) 

print dad.gets_drink() 
print son.gets_drink() 

bu örnekte yapılır yolu çalışır, ancak bir çağrıyla yöntemini değiştirerek, bana nedense garip görünüyor sadece dekoratör koymak mümkün orijinal yöntemle. Ayrıca, bunun çalışması için, yöntemin üst sınıfta bir sınıf olarak tanımlanması gerekir.

Bir şey mi eksik? Geliştiriciler bunu nasıl yapar?

Herhangi bir yardım, içgörü, eleştirel yorum ve ücretsiz kahve çok takdir edilmektedir!

+1

: sözdizimi

@decorator_expression def function_definition(): pass 

için sadece sözdizimsel şeker olduğundan

Bu çalışır. 'Gets_drink' yerine orijinaline yapılan bir çağrı ile neden değiştirdiniz? –

+2

Bir dekoratör kullanmanın, orijinali aramak için 'super()' işlevini kullanmaktan daha kalıtsal bir yöntemi büyütmenin daha iyi bir yolu olup olmadığını bilmek mi istiyorsunuz? –

+0

@MartijnPieters: başlangıçta, çocuk sınıfındaki nesnelerin bazı argümanlarını değiştirmek istedim ve bildiğim kadarıyla bu bir dekoratör ile kolayca yapılabilir. – jojo

cevap

7

Dekoratör sözdiziminde bir dekoratör kullanmak için kullanamazsınız. Bu sadece bir çağrılabilir:

class Child(Person): 
    def __init__(self, age): 
     Person.__init__(self, age=age) 

    gets_drink = dec(Person.gets_drink.__func__) 

Bu, aynı isimde bir yöntem olarak çocuk sınıfına dekoratör dönüş değer katar. __func__ özniteliği, özgün işlevi almayı engelleyen (sınıf) yöntemini açar.

Yeni yönteminizin artık bir yöntem değil, normal bir yöntem olduğunu unutmayın; sonucu classmethod() numaralı çağrıya yeniden sarmanız gerekir. Seni burada aşağıdaki değilim

def function_definition(): 
    pass 
function_definition = decorator_expression(function_definition) 
+0

Harika, cevap için teşekkürler! Örnekte, bu yöntem sadece işe yarayan bir sınıf olarak tanımlanmıştır - bir sınıf yöntemi olması gerekmez. Aslında, 'gets_drink' bir classmethod değilse, o zaman '__func__' da gerekli olmamalıdır. – jojo

+0

@jojo: Python 2'de, ilişkisiz bir yöntem nesnesi döndürülürken '__func__' kullanmak isteyebilirsiniz. Geri sarma, ebeveyn sınıfına ve katmanlamaya gereksiz bir başvuru eklemekten kaçınır. Python 3'te, sınıftaki işleve erişmek yalnızca işlevi döndürür. –

+0

Ama hala merak ediyorum, örnekte nasıl kötü bir yaklaşım yaptım? – jojo

İlgili konular