好吧,先说第一件事。
Python 中不存在“变量声明”或“变量初始化”之类的东西。
这就是我们所说的“赋值”,但也许应该称之为“命名”。
赋值意味着“左侧的这个名称现在指的是评估右侧的结果,无论它之前引用了什么(如果有的话)”。
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 的名称(可以说是比“变量”更好的术语)没有关联的类型;价值观确实如此。您可以将相同的名称重新应用于任何事物,无论其类型如何,但该事物仍然具有依赖于其类型的行为。名称只是引用值(对象)的一种方式。这回答了你的第二个问题:你don't创建变量来保存自定义类型。您不需要创建变量来保存任何特定类型。您根本不“创建”变量。你给物体命名。
第二点:Python 在类方面遵循一个非常简单的规则,实际上比 Java、C++ 和 C# 等语言的一致性要高得多:里面声明的所有内容class
块是类的一部分。所以,函数 (def
)这里写的是方法,即类对象的一部分(不是按实例存储),就像 Java、C++ 和 C# 中一样;但这里还有其他名字also课程的一部分。同样,名称只是名称,它们没有关联的类型,并且函数也是对象在Python中。因此:
class Example:
data = 42
def method(self): pass
类也是对象,在Python中。
所以现在我们创建了一个object named Example
,它代表所有事物的类别Example
s。该对象有两个用户提供的属性(在 C++ 中,“成员”;在 C# 中,“字段或属性或方法”;在 Java 中,“字段或方法”)。其中一位被命名为data
,它存储整数值42
。另一个的名字叫method
,它存储一个函数对象。 (Python 自动添加了更多属性。)
不过,这些属性仍然不是对象的真正一部分。从根本上说,一个对象只是更多名称(属性名称)的捆绑,直到您深入了解无法再分割的事物。因此,如果您有意设置的话,值可以在类的不同实例之间共享,甚至可以在不同类的对象之间共享。
让我们创建一个实例:
x = Example()
现在我们有一个名为的单独对象x
,这是一个实例Example
. The data
and method
实际上并不是对象的一部分,但我们仍然可以通过以下方式查找它们x
因为 Python 在幕后做了一些魔法。当我们抬头看时method
,特别是,我们将得到一个“绑定方法”(当我们调用它时,x
自动传递为self
参数,如果我们查找就不会发生这种情况Example.method
直接地)。
当我们尝试使用时会发生什么x.data
?
当我们检查它时,首先在对象中查找它。如果在对象中没有找到,Python 就会在类中查找。
然而,当我们分配给 x.data
,Python将在对象上创建一个属性。它会not替换类的属性。
这使我们能够做object初始化。 Python会自动调用该类'__init__
创建新实例时的方法(如果存在)。在此方法中,我们可以简单地分配给属性来为每个对象上的该属性设置初始值:
class Example:
name = "Ignored"
def __init__(self, name):
self.name = name
# rest as before
现在我们必须指定一个name
当我们创建一个Example
,并且每个实例都有自己的name
。 Python会忽略class属性Example.name
每当我们查找.name
实例的属性,因为首先会找到实例的属性。
最后一个警告:修改(变异)和赋值是不同的事情!
在 Python 中,字符串是不可变的。它们不能被修改。当你这样做时:
a = 'hi '
b = a
a += 'mom'
You 不要换原始的“hi”字符串。这在 Python 中是不可能的。相反,您创建一个new string 'hi mom'
,并导致a
不再是一个名字'hi '
,并开始成为'hi mom'
反而。我们创造b
一个名字'hi '
以及重新应用后a
name, b
仍然是一个名字'hi '
, 因为'hi '
仍然存在并且没有改变。
但列表可以更改:
a = [1, 2, 3]
b = a
a += [4]
Now b
也是 [1, 2, 3, 4],因为我们做了b
同一事物的名称a
命名,然后我们改变了那个东西。我们没有创建新列表a
命名,因为Python只是简单地对待+=
对于列表则不同。
这对于对象很重要,因为如果您有一个列表作为类属性,并使用一个实例来修改该列表,那么该更改将在所有其他实例中“看到”。这是因为 (a) 数据实际上是类对象的一部分,而不是任何实例对象; (b) 因为您正在修改列表而不是进行简单的赋值,所以您没有创建隐藏类属性的新实例属性。