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
一个实例。 data
和method
实际上并不是对象的一部分,但是我们仍然可以通过x
查看它们,因为Python在幕后有一些神奇的function。 当我们查找method
,特别是,我们将取而代之的是一个“绑定方法”(当我们调用它的时候, x
自动作为self
parameter 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 =无