无法通过getattr\uuu getattr\uu(\uu getattribute_uu)调用

2024-09-29 23:23:22 发布

您现在位置:Python中文网/ 问答频道 /正文

它是容器类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'"


Tags: 方法selfreturnobjectinitdefargargs
3条回答

当您说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__,或者其他方法,然后可以执行您想要的任务)。在

相关问题 更多 >

    热门问题