2014-06-11 21 views
10
>>> class Potato(object): 
...  def method(self, spam): 
...   print self, spam 
... 
>>> spud = Potato() 

İşleri: Niçin ** kendimizi bir yöntem haline getiremiyoruz?

>>> Potato.method(spud, **{'spam': 123}) 
<__main__.Potato object at 0x7f86cd4ee9d0> 123 

Çalışmaz

:

>>> Potato.method(**{'self': spud, 'spam': 123}) 
# TypeError 

Ama neden olmasın? Ben 'kendi' sadece bir kongre olduğunu düşündüm ve bu argüman hakkında asıl olarak özel bir şey yoktu?

+3

Bu ilginç bir soru. Bir düşünce: Bu kurala göre, "benlik", "ben" diye adlandırılmamış, 1'inci argümandır. Belki de ismiyle açılmayı beklemez, ancak – slezica

+1

pozisyonuna göre aynı soruna sahip olursunuz: Potato.method (self = spud, spam = 123) '. Uyarısı gerçekten sorun değil. –

+1

Tam olarak, çünkü 'kendini' sadece bunu yapamayacağınız bir sözleşmedir. "Self" isminin özel bir durumu olmadığı için, Python yalnızca argüman listesinde hangi argümanın "self" olduğunu bilir, çünkü argüman listesinde * ilk * olur, bu yüzden konumsal olarak iletilmelidir. – BrenBarn

cevap

12

Python 2'nin instancemethod sarıcı nesne ilk pozisyonel argüman teftiş ısrar ve bu onay kelime argümanları desteklemez, nokta: Orada açma argümanı kullanmak vermedi

>>> Potato.method(self=spud, spam=123) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method method() must be called with Potato instance as first argument (got nothing instead) 

Not!

>>> Potato.method(*(spud,), **{'spam': 123}) 
<__main__.Potato object at 0x1002b57d0> 123 

veya orijinal işlevi nesneye erişebilen:

sadece ince pozisyonel argümanları kullanabilir

>>> Potato.method.__func__(**{'self': spud, 'spam': 123}) 
<__main__.Potato object at 0x1002b57d0> 123 

bu sınırlamayı atlamak için. Python 3, artık kullanılmayan yöntemler için bir yöntem sarıcı kullanmamaktadır; temel işlev doğrudan yerine döndürülür.

+0

Kaynak referansı: http://hg.python.org/cpython/file/9438a8aa3622/Objects/classobject.c#l2548' self = PyTuple_GET_ITEM (arg, 0); ' kW' dict kontrol etmek için hiçbir girişim ile 2561 hattı. – user2357112

+0

@ user2357112: ve neden * * yapmalı? Bunun yerine, ilk argümanın ismini görmek için istem dışı işlevini gözden geçirmeliyiz; bunların hepsi, metod nesnesinin yerine bir şeyler yazılmasıyla kolayca işlenebilecek bir aşırı uç vakasını desteklemelidir. –

+0

Bu sadece cpython uygulama detayı mı? Argdec'teki ilk argümanın argüman ismiyle eşleşen bir kwarg aramak için kwargs etrafında kazmak _did_ hala "python" olarak adlandırılır mı? _edit: _ Bu sorunun cevabı, bağlantılı kopyada adreslenir. – wim

İlgili konular