Pythonvariables声明

学习python,有一些基本的疑问。

我已经看到variables声明(这里是path)

class writer: path = "" 

有时,没有明确的声明,但通过__init__初始化。

 def __init__(self, name): self.name = name 

我理解__init__的目的,但build议在其他函数中声明variables。

2.如何创buildvariables来保存自定义types?

 class writer: path = "" # string value customObj = ?? 

好的,首先是事情。

Python中没有“variables声明”或“variables初始化”这样的东西。

简而言之,我们称之为“分配”,但应该只是称为“命名”。

分配意味着“现在左边的这个名字是指评估右边的结果,而不pipe它之前提到的是什么(如果有的话)”。

 foo = 'bar' # the name 'foo' is now a name for the string 'bar' foo = 2 * 3 # the name 'foo' stops being a name for the string 'bar', # and starts being a name for the integer 6, resulting from the multiplication 

因此,Python的名字(可以说是比“variables”更好的名词)没有关联types; 值是这样的。 你可以重新应用相同的名字,而不pipe它的types如何,但是这个东西仍然有依赖于它的types的行为。 该名称只是一种引用值(对象)的方法。 这回答你的第二个问题:你创buildvariables来保存自定义types。 您不要创buildvariables来保存任何特定的types。 你根本不“创造”variables。 你把名字给对象。

第二点:对于类来说,Python遵循一个非常简单的规则,实际上它比Java,C ++和C#等语言更加一致: class块中声明的所有内容都是class的一部分 。 所以,这里写的函数( def )就是方法,也就是类对象的一部分(不是以每个实例为基础),就像在Java,C ++和C#中一样。 但这里的其他名字也是这个类的一部分。 同样,名称只是名称,它们没有关联的types, 函数也是 Python 中的对象 。 从而:

 class Example: data = 42 def method(self): pass 

类也是 Python 中的对象

所以现在我们创build了一个名为Example对象 ,它代表了所有Example的类。 该对象具有两个用户提供的属性 (在C ++中,“成员”;在C#中,“字段或属性或方法”;在Java中,“字段或方法”)。 其中之一是命名data ,它存储整数值42 。 另一个是命名method ,它存储一个函数对象。 (还有几个Python自动添加的属性。)

尽pipe如此,这些属性仍然不是对象的一部分。 从根本上说,一个对象只是一堆更多的名称(属性名称),直到你find不能再被分割的东西。 因此,如果你故意设置这个值,那么值可以在一个类的不同实例之间共享,甚至可以在不同类的对象之间共享。

我们来创build一个实例:

 x = Example() 

现在我们有一个名为x的单独对象,它是Example一个实例。 datamethod实际上并不是对象的一部分,但是我们仍然可以通过x查看它们,因为Python在幕后有一些神奇的function。 当我们查找method ,特别是,我们将取而代之的是一个“绑定方法”(当我们调用它的时候, x自动作为selfparameter passing,如果直接查找Example.method就不会发生)。

当我们尝试使用x.data时会发生什么?

当我们检查它时,首先在对象中查找它。 如果在对象中没有find,Python将在类中查找。

但是,当我们分配给 x.data ,Python将在对象上创build一个属性。 它不会replace类的属性。

这允许我们做对象初始化。 Python会在新实例创build时自动调用类的__init__方法,如果存在的话。 在这个方法中,我们可以简单地分配给属性来为每个对象的属性设置初始值:

 class Example: name = "Ignored" def __init__(self, name): self.name = name # rest as before 

现在我们必须在创build一个Example时候指定一个name ,每个实例都有自己的name 。 每当我们查找实例的.name ,Python都会忽略class属性Example.name ,因为实例的属性将首先被find。

最后一个警告: 修改(突变)和任务是不同的东西!

在Python中,string是不可变的。 他们不能被修改。 当你这样做时:

 a = 'hi ' b = a a += 'mom' 

不会改变原来的“嗨”string。 在Python中这是不可能的。 相反,你创build一个新的string'hi mom' ,并导致a不再是'hi '的名称,而是开始为'hi mom'的名称。 我们也把'hi '命名为b ,在重新申请a名字后, b仍然是'hi '的名字,因为'hi '依然存在而且没有改变。

但是名单可以改变:

 a = [1, 2, 3] b = a a += [4] 

现在b也是[1,2,3,4],因为我们把b命名为一个名字相同的东西,然后我们改变了这个东西。 我们没有为a名字创build一个新的列表,因为Python对于列表只是简单地对待+=

这对于对象很重要,因为如果你有一个列表作为一个类的属性,并使用一个实例来修改列表,那么在所有其他实例中,这个修改将被“看到”。 这是因为(a)数据实际上是类对象的一部分,而不是任何实例对象; (b)因为你正在修改列表而不做一个简单的赋值,所以你没有创build一个隐藏类属性的新实例属性。

没有必要在Python中声明新的variables。 如果我们正在讨论函数或模块中的variables,则不需要声明。 只需在需要的地方给一个名字赋值: mymagic = "Magic" 。 Python中的variables可以保存任何types的值,并且不能限制这些值。

尽pipe你的问题具体问到类,对象和实例variables。 创build实例variables的惯用方法是在__init__方法中,而不是在其他地方 – 而您可以在其他方法中创build新的实例variables,甚至在不相关的代码中创build新的实例variables,这只是一个坏主意。 它会使你的代码难以推理或维护。

举个例子:

 class Thing(object): def __init__(self, magic): self.magic = magic 

简单。 现在这个类的实例有一个magic属性:

 thingo = Thing("More magic") # thingo.magic is now "More magic" 

在类的名称空间中创buildvariables本身会导致不同的行为。 它在function上是不同的,只有你有特定的理由时才应该这样做。 例如:

 class Thing(object): magic = "Magic" def __init__(self): pass 

现在尝试:

 thingo = Thing() Thing.magic = 1 # thingo.magic is now 1 

要么:

 class Thing(object): magic = ["More", "magic"] def __init__(self): pass thing1 = Thing() thing2 = Thing() thing1.magic.append("here") # thing1.magic AND thing2.magic is now ["More", "magic", "here"] 

这是因为类本身的命名空间不同于从它创build的对象的命名空间。 我会留给你去研究一下。

回家的信息是,惯用的Python是(a)初始化你的__init__方法中的对象属性,(b)根据需要logging你的类的行为。 你不需要为所写的所有内容去find完整的狮身人面像级文档的麻烦,但至less对你或其他人可能需要的任何细节进行评论。

variables有一定的范围,所以是适当的variables是特定于你的function。 你并不总是必须明确他们的定义。 通常你可以使用它们。 只有当你想做一些特定于variablestypes的事情,比如追加列表,你是否需要在开始使用它们之前定义它们。 这是典型的例子。

 list = [] for i in stuff: list.append(i) 

顺便说一下,这不是一个真正的设置列表的好方法。 最好是说:

 list = [i for i in stuff] # list comprehension 

但是我离题了

你的其他问题。 自定义对象应该是一个类本身。

 class CustomObject(): # always capitalize the class name...this is not syntax, just style. pass customObj = CustomObject() 

为了范围的目的,我使用 –

custom_object =无