python-3.x TypeError:描述符“__weakref__”不适用于父__str__方法中的对象

yvfmudvl  于 2023-03-24  发布在  Python
关注(0)|答案(2)|浏览(104)

我有一个父类,让我们称之为A和一堆子类,BCD等。我想在父类上定义一个__str__()方法,并在其中通过dir(self)访问子类的成员。它可以工作,但当我检查名称是否是callable(getattr(self, attr))的可调用时,我得到:
TypeError:'A'对象的描述符'__weakref__'不适用于'B'对象
引发错误的代码如下:
[attr for attr in dir(self) if not callable(getattr(self, attr)) and not attr.startswith("__")]
有人能解释一下这是什么意思吗?
侧记:我设法让所有的类成员循环通过self.__dict__,我的问题只是出于好奇,因为我不能理解错误。

编辑

我做了一个更简单的代码版本:

class A():

    def __init__(self):
        pass

    def test(self, par):
        print('10')

    def __str__(self):
        members = [attr for attr in dir(self) if not callable(getattr(self, attr)) and not attr.startswith("__")]

        str = ''
        for m in members:
            str += m
            str += ','

        return str

class B(A):

    def test_b(self, par):
        print('10_b')

    def __init__(self,first,second):
        self.first = first
        self.second = second

if __name__ == '__main__':   
    b = B('one', 'two')
    print(b)

但是这里的代码可以正常工作并正确地打印first,second,
原始代码被打包,A和B的等价物在一个单独的包中,由“main”脚本调用。实际代码中类的__str__()方法中的相同代码会引发错误。

hs1rzwqc

hs1rzwqc1#

你的代码中有一些非常奇怪的东西。如果有机会找到问题,你需要给予更多的细节。你引用的错误只在一个地方(这里)被提出-在一个方法中,防止来自一个类的描述符(如__weakref__)被用于另一个不兼容的类型。
我可以重现错误的唯一方法(并拥有B子类A)是这样的:

class A:
    pass

class Z:
    pass

class B(A,Z):
    pass

B.__weakref__.__get__(A()) # works
B.__weakref__.__get__(Z()) # fails

# because
assert B.__weakref__ == A.__weakref__ # is true
assert B.__weakref__ == Z.__weakref__, 'B uses A.__weakref__ rather than  Z.__weakref__'
py49o6xq

py49o6xq2#

我有一个使用带插槽的dataclasses的这个bug的更简单的例子:

from dataclasses import dataclass

@dataclass(slots=True)
class Bug:
    field1: str

bug = Bug("hello, world")
assert "__weakref__" in dir(bug)
getattr(bug, "__weakref__")

相关问题