为什么在Python中使用“declare”变量?

2024-03-29 06:06:58 发布

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

我之前在google上搜索了一些与Python相关的问题,偶然发现了this页面。作者做了如下工作:

class TestClass(object):
    first = str()
    def __init__(self):
        self.first = "Hello"

像这样“声明”变量first有什么意义?我以前从未见过这样做过,而且我一辈子都无法想到在给变量赋值之前先创建一个变量是有益的。在

上面的例子也可以是这样的:

^{pr2}$

……还是我遗漏了什么?在


Tags: self声明helloobjectinitdefgoogle作者
3条回答

str()等于""

>>> str()
''

我想作者想展示实例属性覆盖具有相同名称的类属性。等等执行

^{pr2}$

您将获得:

^{3}$

不是

{'second': '', 'third': '', 'first': ''}

但是

print testclass.__dict__

将打印类属性:

{'__module__': '__main__', 'third': '', 'second': '', '__doc__': None, '__init__': <function __init__ at 0xb5fed6bc>, 'first': ''}

作者使用

first = str()

与之相反

^{pr2}$

除了在__init__中设置self.first之外,还表明这样做没有任何意义。在

也许作者很困惑,认为python变量需要先声明并在查看链接时很明显

这不是一个声明,这是一个任务。。。类中的变量,而不是实例中的变量。在

考虑以下输出:

>>> class K1(object):
...     def __init__(self):
...         self.attr = 'value'
... 
>>> x = K1()
>>> x.__dict__
{'attr': 'value'}
>>> class K2(object):
...     attr = 'value'
...     def __init__(self):
...         self.another = 'value2'
... 
>>> y = K2()
>>> y.__dict__
{'another': 'value2'}

这里x是类K1的一个实例,有一个名为attr的属性,y是类K2的实例,有一个不同的属性another。但是:

^{pr2}$

那是从哪里来的?它来自课堂:

^{3}$

这有点乱,但是你可以看到attr坐在那里。如果你看x.__class__.__dict__没有{}:

>>> x.__class__.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'K1' objects>,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'K1' objects>,
'__doc__': None, '__init__': <function __init__ at 0x80185b938>})

当您获得实例的属性时,比如x.attry.attr,Python首先查找附加到实例本身的东西。如果什么也没找到,它会“向上看”看是否有其他东西定义了这个属性。对于具有继承的类,这涉及到遍历“成员解析顺序”列表。在本例中,不需要担心继承,但下一步是查看类本身。这里,在K2中,类中有一个名为attr的属性,这就是y.attr生成的。在

您可以更改class属性以更改y.attr中显示的内容:

>>> K2.attr = 'newvalue'
>>> y.attr
'newvalue'

实际上,如果您创建K2()的另一个实例,它也会获取新值:

>>> z = K2()
>>> z.attr
'newvalue'

请注意,更改x的attr不会影响K1()的新实例:

>>> w = K1()
>>> w.attr = 'private to w'
>>> w.attr
'private to w'
>>> x.attr
'value'

这是因为w.attr实际上是w.__dict__['attr'],而{}实际上是{}。另一方面,y.attr和{}实际上都是y.__class__.__dict__['attr']和{},由于y.__class__和{}都是{},因此K2.attr同时改变。在

(不过,我不确定写原始问题中提到的那一页的人是否意识到了这一切。创建一个类级别的属性,然后创建一个具有相同名称的实例级属性,这有点毫无意义。)

相关问题 更多 >