列出namedtuple子类的属性

python attributes subclass python-3.3 namedtuple

1094 观看

3回复

4587 作者的声誉

我有一个扩展a的小类namedtuple,但__dict__它的实例的属性总是返回空。

Point = namedtuple('Point', 'x y')
p1 = Point(20, 15)
print(p1, p1.__dict__)
# Point(x=20, y=15) OrderedDict([('x', 20), ('y', 15)]) <--- ok

class SubPoint(Point): pass
p2 = SubPoint(20, 15)
print(p2, p2.__dict__)
# SubPoint(x=20, y=15) {} <--- why is it empty?

p2有属性,但它__dict__是空的。dir()但是,它们被正确列出,这很奇怪。SubPoint扩展一个vanilla类时请注意这项工作正确。

发生了什么,我如何列出我的子类实例中的属性?

作者: BoppreH 的来源 发布者: 2014 年 3 月 31 日

回应 (3)


0

4587 作者的声誉

__slots__ = ()在子类中声明修复了问题,但原因尚不清楚。据我所知,__slots__不应该以这种微妙的方式改变代码的行为,所以这不是一个完整的答案。

Point = namedtuple('Point', 'x y')
p1 = Point(20, 15)
print(p1, p1.__dict__)
# Point(x=20, y=15) OrderedDict([('x', 20), ('y', 15)]) <--- ok

class SubPoint(Point):
    __slots__ = ()
p2 = SubPoint(20, 15)
print(p2, p2.__dict__)
# SubPoint(x=20, y=15) OrderedDict([('x', 20), ('y', 15)]) <--- fixed

欢迎回答一个解释。

作者: BoppreH 发布者: 31.03.2014 04:43

4

185316 作者的声誉

决定

问题是__slots__它只限于它所定义的类,所以基类__dict__除了你__slots__在那里定义之外总是有自己的属性。(还要注意,__dict__属性namedtuple不是普通的dict而是@property。)

来自docs

一个的动作__slots__声明限制为定义它的类。因此,子类将具有一个,__dict__除非它们也定义__slots__(它必须只包含任何其他槽的名称)。

因此,当您__slots__在子类中定义时,它无法__dict__在该类中查找属性,因此转移到找到该__dict__属性的基类。

一个简单的演示:

class A:
    __slots__=  ('a', 'b')

    @property
    def __dict__(self):
        print ('inside A')
        return self.__slots__         

class B(A):
    pass

print(B().__dict__)

print ('-'*20)

class B(A):
    __slots__ = ()
print(B().__dict__)

输出:

{}
--------------------
inside A
()
作者: Ashwini Chaudhary 发布者: 31.03.2014 05:15

0

41 作者的声誉

list(A.__annotations__.keys())
作者: WolvhLorien 发布者: 14.08.2019 10:28
32x32