它是容器类tmpA中的类A的对象。不是所有方法
来自tmpA的。例如:
A+B存在,tmpA+B不存在。我尝试为tmpA从A调用方法。我
可以调用简单方法,如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'"
当您说
tmp_a + b
时,Python先在tmp_a.__class__.__dict__
中查找__add__
方法(绕过hasattr/getattr类型查找)因为在任何地方都找不到它,Python会查看
b
是否有一个__radd__
方法,该方法可以将tmp_a
作为另一个参数处理。既然不能,就抛出异常。在您必须向tmpA添加一些特殊的方法才能使它们正常工作。在
我认为}。在
X + Y
被认为是{所以如果你用
class tempA(A)
然后temp_a + b
工作,因为它继承了__add__
方法并像temp_a.__add__(b)
一样使用它。在但是如果你用
当遇到}方法来调用。在
class tempA(object)
时,class tempA(object)
中没有{在类的实例上查找的特殊方法,即不在类的实例上查找(除了旧式类中的一些不规则,这只是一个巨大的头痛)。因此,特别是类的
__getattr__
(对于正常的新类型的类)是而不是在执行+
时被调用来查找__add__
,元类的(type
,这里)__getattr__
是。在“从
object
中删除继承”意味着重新回到旧式类的hellzapoppin世界,只会为未来积蓄痛苦:不要!相反,如果你有一个类必须委托一些特殊的方法,那么在类中显式地编码它们(直接地或通过类装饰器),或者创建一个知道这种怪癖的自定义元类(元类的__getattr__
,或者其他方法,然后可以执行您想要的任务)。在相关问题 更多 >
编程相关推荐