2016-04-11 24 views
7

Python'da, bir nesnenin __add__ yöntemini (veya diğer çift alt çizgi aka "dunder" yöntemlerini) aşırı yükleyebilirim. Bu, Python operatörlerini kullanırken nesnelerim için özel davranışı tanımlamamı sağlar.Bir nesnede çağrılan + veya __add__ bilgisinin bilinmesi

Yöntem, + aracılığıyla veya __add__ aracılığıyla çağrılmışsa, dunder yönteminden bilmek mümkün müdür? Örneğin

, doğrudan olarak adlandırılan + kullanılması halinde veya __add__ halinde bağlı "+" veya "__add__" yazdırır bir nesne oluşturmak isteyen varsayalım. method_how_created gibi bazı büyü varlığını Barring

class MyAdder(object): 
    def __add__(self, other): 
     print method_how_created() 
     return 0 


MyAdder() + 7 
# prints "+", returns 0 

MyAdder().__add__(7) 
# prints "__add__", returns 0 

, yöntemleri dunder için sembollerin bir kanonik haritalama var mı? http://www.python-course.eu/python3_magic_methods.php ya da operator modülünün belgesellerini ayrıştırmaya dayalı çözümler var, Access operator functions by symbol. Fonksiyon isimleri ile semboller arasında bir haritayı bulmanın bir yolu var mı?

+8

Neden böyle bir şey istersiniz? – wnnmaw

+1

Lütfen yanılıyorsam düzeltin, ama '' '' '' __add__''ı çağırmıyor mu? –

+1

@ OrangeFlash81 bunu yapar. Ve 'NotImplemented' için' __radd__' ' – Bharel

cevap

5

Evet, ama muhtemelen bunu yapmak istemiyorsunuz, çünkü bu kötü bir fikir. Tercüman kümesini incelemek zorundasınız. kodunuzu C'den denir eğer Belli nedenlerden dolayı, bu İşte kod çalışmaz:

import inspect 
import dis 

class A(object): 
    def __add__(self, other): 
     fr = inspect.getouterframes(
      inspect.currentframe(), 1)[1][0] 
     opcode = fr.f_code.co_code[fr.f_lasti] 
     # opcode = ord(opcode) # Uncomment for Python 2 
     is_op = opcode == dis.opmap['BINARY_ADD'] 
     if is_op: 
      print('Called with +') 
     else: 
      print('Called with __add__') 

A() + 1 
A().__add__(1) 

Bu ise Python 2.

+0

Bunun neden kötü bir fikir olacağını açıklar mısınız? Bu, Cython ya da PyPy gibi C-olmayan python uygulamalarında işe yaramayacağı için mi? Tercüman kümesini incelemek her zaman kötü bir fikir midir, eğer öyleyse, neden? – cjrieds

+1

Bu kötü bir fikir olurdu çünkü (1) alışılmadık ve şaşırtıcı olana göre farklı davranan bir işlev yaratır ve (2) '__add __()' yöntemi ile aynı olması gerekir. + 've farklı davranmasını sağlamak sadece insanları karıştırıp kızdırmaktır. Doğru, bu kodu kullanan birisi böyle bir canavarı yaratmak için sana * kızabilir. –

+0

Ek soru-- Özür dilerim ama bunun neden C'den işe yaramayacağı açık değil. Açıkla veya bir açıklama ile bağlantıya işaret edebilir misiniz? – cjrieds

4

için sadece küçük değişiklikler test edilmiş ve Python 3 ile çalışır ve gerektirir cpython, yönlendirme çerçevesini sökerek bazı iç gözlem yeteneklerine sahip olursunuz. Örneğin:

import dis 
import inspect 

def method_how_created(): 
    return dis.dis(inspect.currentframe().f_back.f_back.f_code) 

class MyAdder(object): 
    def __add__(self, other): 
     print method_how_created() 

x = MyAdder() 

durumda x + 7 kontrol etme sen sökme içinde böyle bir şey göreceksiniz: sihirli yöntem x.__add__(7) kullanma

  64 LOAD_NAME    5 (x) 
     67 LOAD_CONST    5 (7) 
     70 BINARY_ADD   
     71 POP_TOP    
     72 LOAD_CONST    1 (None) 
     75 RETURN_VALUE   

, sen sökme içinde böyle bir şey göreceksiniz:

  64 LOAD_NAME    5 (x) 
     67 LOAD_ATTR    6 (__add__) 
     70 LOAD_CONST    5 (7) 
     73 CALL_FUNCTION   1 
     76 POP_TOP    
     77 LOAD_CONST    1 (None) 
     80 RETURN_VALUE   
İlgili konular