它是A类的对象,在容器的类tmpA中。不是所有方法
来自A是在tmpA。例如:
存在A + B,不存在tmpA + B.我尝试从A调用tmpA的方法。一世
可以调用简单方法,例如change(),但__add__
- 不要
工作。如果要从对象中删除继承,代码可以正常工作。
#--------------------------------------
class A(object):
def __init__( self, x, y ):
self.x = x
self.y = y
pass
#-------
def __add__( self, arg ):
tmp1 = self.x + arg.x
tmp2 = self.y + arg.y
return tmpA( A( tmp1, tmp2 ) )
def change( self, x, y ):
self.x = x
self.y = y
pass
pass
#------------------------------------------
class tmpA( object ):
def __init__( self, theA ):
self.A = theA
pass
#-------
def _print ( self ):
print " x =", self.A.x
print " y =", self.A.y
pass
#-------
def __call__( self ):
return self.A
#-------
def __coerce__( self, *args ):
return None
#-------
def __getattr__( self, *args ):
name = args[ 0 ]
try:
attr = None
exec "attr = self.__call__().%s" % name
return attr
except :
raise AttributeError
#--------------------------------------
class B( object ):
def __init__( self, x, y):
self.x = x
self.y = y
pass
#-------------------------------------
a=A( 1,2 );
b=B( 3,4 );
tmp_a = a + b;
tmp_a.change( 0, 0 ) # very well
v = tmp_a + b #TypeError: "unsupported operand type(s) for +: 'tmpA' and 'B'"
答案 0 :(得分:5)
在班级的实例上查找特殊方法 ,即不(旧的一些违规行为除外)风格的课程,这只是一个巨大的问题)。所以特别是类__getattr__
(对于理智,新风格的类)不在执行__add__
时调用+
- 元类的(type
,此处)__getattr__
是。
“从object
删除继承”意味着重新回到旧式课程的hellzapoppin世界,只会存储未来的痛苦:不要!相反,如果你有一个必须委托一些特殊方法的类,在类中直接或通过类装饰器显式编写它们,或者创建一个知道这个怪癖的自定义元类(元类的__getattr__
或其他意味着,然后可以执行你渴望的任务。)
答案 1 :(得分:2)
我认为X + Y
被视为X.__add__(Y)
。
所以如果你使用
class tempA(A)
然后temp_a + b
有效,因为 继承了 __add__
方法并将其用作temp_a.__add__(b)
。
但是如果你使用
class tempA(object)
然后在遇到__add__
时,class tempA
中没有temp_a + b
方法进行调用。
答案 2 :(得分:1)
当你说tmp_a + b
时,Python查找tmp_a.__class__.__dict__
然后object.__dict__
查找__add__
方法(绕过hasattr / getattr类型查找)
由于在任何地方都找不到,因此Python会查看b
是否有__radd__
方法可以将tmp_a
作为另一个参数处理。由于它不能,抛出异常。
您必须向tmpA添加一些特殊方法才能使这些方法正常工作。