在类中编写代码与在Python中在def________;(self)中编写代码有什么区别?

在类中编写代码与在Python中在def________;(self)中编写代码有什么区别?,python,class,init,Python,Class,Init,可能重复: 我知道,当调用一个类时,它会先在_uinit_uuu中运行代码。我仍然没有看到这与直接在类下编写代码之间的区别 例如: class main(): x = 1 def disp(self): print self.x 对我来说,两者都有相同的功能。也许我错过了什么。我想知道哪一个更像是一条蟒蛇,以及为什么。它是不同的。 在第一个示例中,您有没有初始化的x >>> class main(): ... def __init__(self):

可能重复:

我知道,当调用一个类时,它会先在_uinit_uuu中运行代码。我仍然没有看到这与直接在类下编写代码之间的区别

例如:

class main():
  x = 1

  def disp(self):
    print self.x
对我来说,两者都有相同的功能。也许我错过了什么。我想知道哪一个更像是一条蟒蛇,以及为什么。

它是不同的。 在第一个示例中,您有没有初始化的x

>>> class main():
...     def __init__(self):
...             self.x =1
...
>>> test2 = main()
>>> dir(test2)
['__doc__', '__init__', '__module__', 'x']
>>> class main1():
...     x =1
...     def disp(self):
...             print self.x
...
>>> dir(main1)
['__doc__', '__module__', 'disp', 'x']
>>> dir(main)
['__doc__', '__init__', '__module__']
>>>

是的,正如在各种其他问题中所述,在类主体中定义的变量是类的属性,而在def uu init u self块中定义的变量是类实例的属性


这里有两个关键的区别,一个是初始化,另一个是在类下面写,还有你写的东西

使用x=1工作
首先,您是对的,这两项代码在您的目的上有效地做了相同的事情,特别是因为我们在这里处理int对象,这对于可变对象是不同的:

请注意,他们实际上并没有做相同的事情。请参阅此答案上的评论以获得澄清

类主对象: x=1 类主对象: 定义初始自我: self.x=1 这就是为什么许多非标准Python库,如mongoengine和django模型,都有一个标准,您可以在不使用uu init uuu语句的情况下创建类,这样就不会覆盖内置的类,但仍然可以创建类属性,例如django示例:

类mymodelmodels.model: 名称=型号。CharFieldmax_长度=20 url=models.UrlField 然而,正如另一张海报所指出的,两者之间的区别在于,当x=1在_init _函数之外时,它是类本身的一部分,即使在没有初始化的情况下,也可以参见Zagorulkin Dmitry的答案以了解更多细节。不过,在大多数情况下,这种区别与你无关

其他考虑 除了设置变量之外,init还有更多的用途。最重要的一点是能够在初始化期间接受参数。据我所知,没有uu init uu函数是无法做到这一点的。在这个例子中,我将向您展示我的意思

假设我们正在创建一个Person类,当我们创建一个Person时,我们提供了他们的年龄,然后他们的出生年份会自动为我们计算出来

导入日期时间 类Personobject: 定义初始自我,年龄: self.age=年龄 self.birth\u year=datetime.date.today-datetime.timedeltadays=age*365.year 使用中:

>>>乔=人23 >>>乔·阿格 23 >>>乔,今年出生 1990

这是不可能的,因为我们不能通过初始化的年龄参数否则,< /P> < P>让我们考虑下面的类定义:

class Main:
        x = 1

        def __init__(self):
            self.y = 5
在这种情况下,我们可以直接引用x,如:Main.x,即它是一个类属性,它属于这个类的每个对象

>>>Main.x
1
但是,属性y特定于每个对象。我们不能这样直接引用:

>>> Main.y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class Main has no attribute 'y'

这与C++和java中的静态变量类似。如已经指出的,在类级别分配的类属性和赋值为自属性的实例属性,例如在y.iNITSY中是不同的。 另一方面,在第一个类中,您定义了两个不同的属性class x和instance x,它们共存,但可能相互干扰。下面的代码试图说明如果以这种方式定义类,可能会遇到的问题

In [32]: class main():
   ....:     x = 1
   ....:     def disp(self):
   ....:         print(self.x)
   ....:

# I create 2 instances
In [33]: jim = main()
In [34]: jane = main()

# as expected...:
In [35]: main.x
Out[35]: 1

In [36]: jim.x
Out[36]: 1

In [37]: jane.x
Out[37]: 1

# now, I assign to jim attribute x
In [38]: jim.x = 5

# main class preserves its attribute value as well as jane instance  
In [39]: main.x
Out[39]: 1

In [40]: jane.x
Out[40]: 1

# But what happens if I change the class attribute ?
In [41]: main.x = 10

# nothing to jim (I overwrote before jim.x)
In [42]: jim.x
Out[42]: 5

# but jane did see the change 
In [43]: jane.x
Out[43]: 10

你没有考虑在你输入这个问题时提出的类似问题吗?我确实试过先搜索。重复的太多了。非常抱歉!这是一个明显的例子。但这是一个重复的问题。我应该做什么>。这两项代码有效地完成了相同的事情。不是真的。第一个是类属性,第二个生成每个实例属性。在OP给出的示例中,x即main.x和self.x是共存的不同变量,因此可以独立修改,除非您分配给实例。这是一个公平的观点,我更新了我的答案以供参考。所有答案都可以说是好的。但我之所以选择它,是因为在初始化示例期间接受参数的示例。这非常有帮助。这是一个很好的例子,但请注意,OP代码在声明具有相同名称x的类和实例变量时隐藏了一些意外
>>> obj = Main()
>>> obj.y
5
In [32]: class main():
   ....:     x = 1
   ....:     def disp(self):
   ....:         print(self.x)
   ....:

# I create 2 instances
In [33]: jim = main()
In [34]: jane = main()

# as expected...:
In [35]: main.x
Out[35]: 1

In [36]: jim.x
Out[36]: 1

In [37]: jane.x
Out[37]: 1

# now, I assign to jim attribute x
In [38]: jim.x = 5

# main class preserves its attribute value as well as jane instance  
In [39]: main.x
Out[39]: 1

In [40]: jane.x
Out[40]: 1

# But what happens if I change the class attribute ?
In [41]: main.x = 10

# nothing to jim (I overwrote before jim.x)
In [42]: jim.x
Out[42]: 5

# but jane did see the change 
In [43]: jane.x
Out[43]: 10