首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列出namedtuple子类的属性

列出namedtuple子类的属性
EN

Stack Overflow用户
提问于 2014-03-31 04:34:46
回答 4查看 2.5K关注 0票数 6

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

代码语言:javascript
复制
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扩展普通类时,这项工作是正确的。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-10-05 06:58:49

要了解为什么__dict__不能工作,请检查Ashwini Chaudhary的答复。这个答案涵盖了问题的第二部分(如何列出namedtuple属性)。

要列出namedtuple属性,有_fields_asdict

代码语言:javascript
复制
>>> import collections as c
>>> Point = c.namedtuple("Point", ["x", "y"])
>>> p1 = Point(20, 15)
>>> print(p1._fields)
('x', 'y')
>>> print(p1._asdict())
{'x': 20, 'y': 15}
>>> class SubPoint(Point): pass
...
>>> p2 = SubPoint(20, 15)
>>> print(p2._fields)
('x', 'y')
>>> print(p2._asdict())
{'x': 20, 'y': 15}

注意,_fields是在类上定义的,所以您也可以这样做:

代码语言:javascript
复制
>>> print(SubPoint._fields)
('x', 'y')

显然,_asdict需要一个实例,以便它可以使用这些值。

我使用Python3.9.7作为示例,我不确定这些内容是什么时候添加的(可能是知道的人可以评论)。

票数 1
EN

Stack Overflow用户

发布于 2014-03-31 05:15:37

问题是__slots__仅限于在其中定义的类,因此基类将始终拥有自己的__dict__属性,除非您也在那里定义__slots__。(还请注意,__dict__属性namedtuple不是普通dict,而是@财产。)

来自文档

__slots__声明的操作仅限于定义它的类。因此,子类将有一个__dict__,除非它们也定义__slots__ (必须只包含任何附加插槽的名称)。

因此,当您在子类中定义__slots__时,它未能在该类中查找属性__dict__,因此转移到基类,在那里它找到了__dict__属性。

一个简单的演示:

代码语言:javascript
复制
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__)

输出:

代码语言:javascript
复制
{}
--------------------
inside A
()
票数 4
EN

Stack Overflow用户

发布于 2014-03-31 04:43:13

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

代码语言:javascript
复制
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

欢迎有解释的回答。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22753711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档