在__init__之外初始化实例变量时会发生什么

时间:2017-08-03 13:57:28

标签: python software-design

在初始化实例变量(例如self.my_var)的python中,您应该在类__init__函数中执行此操作,以便为每个实例的此变量正确保留内存(&lt ; - 我的错误,见下文)。如果要定义类级变量,可以在函数外部进行,而不使用self前缀。

当您使用__init__前缀的self以外的函数内实例化变量时会发生什么?它的行为就像一个普通的实例变量,有没有令人信服的理由不这样做?除了隐藏代码逻辑的危险之外,这已经足够原因了,但是我想知道如果你这样做,你可能会在内存或其他隐藏的问题上运行吗?

我无法找到在某处讨论的内容。

更新 抱歉

我误解了一些答案,包括第一个和第三个答案Python __init__ and self what do they do?(寻找其他答案) 并认为__init__是一种特殊类型的函数,认为它以某种方式具有内存分配功能(!?)。错误的问题。

4 个答案:

答案 0 :(得分:5)

__init__方法并不特别。使__init__感兴趣的唯一因素是,当您致电MyClass()时,它会被调用。

以下是等效的:

# Set inside __init__
class MyClassA:
    def __init__(self):
        self.x = 0
obj = MyClassA()

# Set inside other method
class MyClassB:
    def my_initialize(self):
        self.x = 0
obj = MyClassB()
obj.my_initialize()

# Set from outside any method, no self
class MyClassC:
    pass
obj = MyClassC()
obj.x = 0

实例变量的作用是在分配它时,它可以在任何地方发生。另请注意,self也不特殊,它只是一个普通的函数参数(实际上,您可以将其命名为self以外的其他内容。)

  

以便为每个实例的此变量正确保留内存。

你不需要"保留记忆"在Python中。对于普通的对象实例,当您指定self.x = 0obj.x = 0时,它有点像在字典中放置一个值。事实上,

# This is sometimes equivalent, depending on how obj is defined
obj.__dict__['x'] = 0

答案 1 :(得分:2)

这与“保留记忆”无关。 Python不是C;在编写Python时,你绝对不应该考虑内存分配。

作为一种动态语言,Python在设置属性时的行为方式完全相同,__init__在创建属性时不具有任何特权。

然而,在那里做的主要原因是它为您的类提供了一致的界面。如果在创建实例时没有至少分配占位符,则访问该属性的任何代码都需要先检查它是否存在。

尽管如此,仍然有很多用例动态注释属性是有用且完全可以接受的。

答案 2 :(得分:0)

__init__是python类的构造函数,当您使用self定义变量时,如self.abc它变为可以使用self或对象访问的对象属性。它在对象创建时初始化。

当您在__init__之外定义变量或在没有self的类中定义任何函数时,它将成为该类的静态属性。并且对于该类的所有实例保持相同。

如果你使用self在类的其他成员函数中定义它,它与__init__中的内容非常类似,它在实例化时不会自动调用,但你必须调用明确地

答案 3 :(得分:0)

我正在寻找这个问题的答案,特别是因为我在方法中使用self而不是__init__方法定义了一个全局变量,并且它不会影响我的代码。 但是当我需要在另一个方法中使用该变量时 - 在调用启动变量的方法之前 - 它不起作用。显然,变量尚未定义! 因此,答案是我们在__init__方法中定义所有全局变量,因为它会在您从类创建实例后执行。因此,从一开始就定义所有变量,并在任何即将到来的方法中随时使用它们 使用普通方法初始化全局变量将强制您在以任何其他方式使用该变量之前先执行此方法。