gpt4 book ai didi

python - 在 Python 类中动态定义实例字段

转载 作者:太空狗 更新时间:2023-10-29 17:02:32 24 4
gpt4 key购买 nike

我是 Python 的新手,主要来自 Java 编程。

我目前正在思考 Python 中的类是如何实例化的。

我理解 __init__(): 就像 Java 中的构造函数。但是,有时 python 类没有 __init__() 方法,在这种情况下我假设有一个默认构造函数,就像在 Java 中一样?

使从 Java 到 Python 的转换稍微困难的另一件事是,在 Java 中,您必须使用类型定义类的所有实例字段,有时还必须使用初始值。在 python 中,所有这些似乎都消失了,开发人员可以即时定义新字段。

例如我遇到过这样的程序:

class A(Command.UICommand):
FIELDS = [
Field( 'runTimeStepSummary', BOOL_TYPE)
]

def __init__(self, runTimeStepSummary=False):
self.runTimeStepSummary = runTimeStepSummary

"""Other methods"""

def execute(self, cont, result):
self.timeStepSummaries = {}
""" other code"""

让我感到困惑(并且让我有点恼火)的是,这个 A 类没有一个名为 timeStepSummaries 的字段,但是开发人员如何才能在方法中间定义一个新字段?还是我的理解不正确?

明确地说,我的问题是在 Python 中,我们能否像本示例中那样在运行时动态地为类定义新字段,或者这个 timeStepSummaries 变量是否是 java 类私有(private)变量的实例?

编辑:我正在使用 python 2.7

最佳答案

I understand that __init__(): is like the constructor in Java.

更准确的说,在Python中__new__是构造方法,__init__是初始化器。当您执行 SomeClass('foo', bar='baz') 时,type.__call__ 方法基本上执行以下操作:

def __call__(cls, *args, **kwargs):
instance = cls.__new__(*args, **kwargs)
instance.__init__(*args, **kwargs)
return instance

一般来说,大多数类都会在必要时定义一个__init__,而__new__更常用于不可变对象(immutable对象)。

However, sometimes python classes do not have an init() method which in this case I assume there is a default constructor just like in Java?

我不确定旧式类,但新式类就是这种情况:

>>>> object.__init__
<slot wrapper '__init__' of 'object' objects>

如果没有显式定义__init__,将调用默认值。

So to be clear, my question is in Python can we dynamically define new fields to a class during runtime like in this example

是的。

>>> class A(object):
... def __init__(self):
... self.one_attribute = 'one'
... def add_attr(self):
... self.new_attribute = 'new'
...

>>> a = A()
>>> a.one_attribute
'one'
>>> a.new_attribute
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'new_attribute'
>>> a.add_attr()
>>> a.new_attribute
'new'

可以随时向实例添加属性:

>>> a.third_attribute = 'three'
>>> a.third_attribute
'three'

但是,可以通过类属性 __slots__ 来限制可以添加的实例属性:

>>> class B(object):
... __slots__ = ['only_one_attribute']
... def __init__(self):
... self.only_one_attribute = 'one'
... def add_attr(self):
... self.another_attribute = 'two'
...

>>> b = B()
>>> b.add_attr()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in add_attr
AttributeError: 'B' object has no attribute 'another_attribute'

(可能需要注意的是,__slots__ 主要用于内存优化 - 不要求对象具有用于存储属性的字典 - 而不是作为一种形式运行时修改预防。)

关于python - 在 Python 类中动态定义实例字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21517740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com