我一直在阅读关于python OOP的文章,特别是这篇文章。
这篇文章的autor有一个描述,然后是一个代码示例:
实例化类的Python语法与函数相同调用
>>> b = int()
>>> type(b)
<type 'int'>
由此,我推断"实例"存在于执行的时刻,而不是之前。当您执行type(b)
时,它是类int()的实例。
但后来我读到了这个堆栈溢出的答案:
Instance是一个变量,用于保存对象的内存地址。
这让我对这个词有点困惑。那么,当我在执行时分配一个变量时,"实例"就被创建了?
最后,ComputerHope中的这一解释指出了一个事实,即实例与变量赋值相同:
function Animal(numlegs, mysound) {
this.legs = numlegs;
this.sound = mysound;
}
var lion = new Animal(4, "roar");
var cat = new Animal(4, "meow");
var dog = new Animal(4, "bark");
动物对象允许腿的数量和声音动物的制作由对象的每个实例来设置。在这种情况下,所有三个实例(狮子、猫和狗)都有相同数量的腿,但是发出不同的声音。
是否有人真的能提供实例何时退出的明确定义
我一直在阅读关于python OOP的文章,特别是一
这篇文章的autor有一个描述,然后是一个代码示例:
实例化类的Python语法与函数相同调用
>>> b = int() >>> type(b) <type 'int'>
还要阅读之前的句子:
一旦你有了一个类,你就可以实例化它,以获得该类型的具体对象(实例),即根据该类的结构构建的对象。
因此,类的实例是以该类为类型的对象。
通过这一点,我推断"实例"在执行时存在,并且以前没有。
是,正确。"实例"one_answers"的实例"是Python中的运行时概念。
当您执行
type(b)
时类int()。
不完全是。
此处的int实例在调用int()
时开始存在1这个过程被称为"实例化",结果(由该调用返回,在本例中分配给b
)是int
的"实例"。
但后来我读到了这个堆栈溢出的答案:
Instance是一个变量,用于保存对象的内存地址。
哦,这不太正确。实例是对象本身(如果您愿意的话,是该内存地址处的值)。多个变量可能绑定到同一个对象(从而绑定到相同的实例)。甚至有一个操作员可以测试:is
>>> a = 5
>>> b = a
>>> a is b
True
这让我对这个词有点困惑。所以当我分配变量?
否,则实例被绑定到该变量。在Python中,将变量视为"值的名称"。因此,将对象绑定到变量意味着为该对象命名。正如我们在上面看到的,一个对象可以有多个名称。
您可以在不将实例分配给任何变量的情况下使用实例,即不命名实例,例如将其传递给函数:
>>> print(int())
0
最后,ComputerHope中的这一解释指出了这样一个事实实例与变量赋值相同:
function Animal(numlegs, mysound) { this.legs = numlegs; this.sound = mysound; } var lion = new Animal(4, "roar"); var cat = new Animal(4, "meow"); var dog = new Animal(4, "bark");
动物对象允许腿的数量和声音动物的制作由对象的每个实例来设置。在这种情况下,所有三个实例(狮子、猫和狗)都有相同数量的腿,但是发出不同的声音。
不幸的是,ComputerHope上的解释可能会让大多数读者感到困惑,而不是帮助他们。首先,它将术语"类"one_answers"对象"混为一谈。他们的意思不一样。类是一种类型的对象的模板。对象和一类对象的模板不是一个概念,就像cookie切割器和cookie不是一回事一样。
当然,在Python中,类是(特殊但不太特殊)对象(类型为type
),在引入class
概念之前,在JavaScript中,通常使用普通对象作为其他对象的模板,这并没有特别的帮助。(后一种方法被称为"基于原型的面向对象"或"基于原型继承"。相比之下,包括Python在内的大多数其他面向对象语言都使用基于类的面向对象/基于类的继承。我不太确定带有class
关键字的现代ECMAScript属于哪一类。)
有人真的能提供一个明确的实例定义吗?
就像我在上面写的那样:类的实例是一个对象,其类型为
因此,一个"实例"总是一个"的实例"。这也回答了标题中关于这个问题的语言学观点
我什么时候应该称它为"实例"?
当您想将其称为"的instance"某个东西(通常是类的)时,您应该将它称为"instance"。
1我还没有说实话。试试这个:
>>> a = int()
>>> b = int()
>>> a is b
True
等等什么?int
的两个调用不应该分别返回新实例,从而返回两个不同的实例吗?
大多数类型都会发生这种情况,但有些内置类型不同,int
就是其中之一。CPython实现的制作者知道小整数被大量使用。因此,他们让CPython一直创建新的,他们只是让它在每次需要相同值时重用相同的整数(相同的对象/实例)。因为Python整数是不可变的,所以通常不会引起任何问题,并且在计算密集型程序中节省了大量内存和对象创建时间。
Python标准允许实现进行这种优化,但AFAIK不要求它们这样做。因此,这应该被视为实现细节,您的程序逻辑永远不应该依赖于此。(不过,您的性能优化可能依赖于它。)
通常在OOP 中
类和对象是面向对象的两个主要方面编程。类创建一个新类型,其中对象是课堂。
如下所述。
因此,每次创建对象时,它都被称为实例。
Python在这个概念上没有什么不同,但与Java等其他语言有点不同。
事实上,在Python中,所有都是一个对象,甚至是类本身。
以下是对其工作原理的简要解释:
考虑这个片段:
>>> class Foo:
... pass
...
>>> type(Foo)
<type 'type'>
>>>
类Foo
是类型type
,它是Python中所有classes
的元类(然而,"旧"类和"新"类之间有区别,更多的是在这里,这里和这里)。
类type
是一个类,它本身就是一个实例:
>>> isinstance(type, type)
True
因此,尽管Foo
是一个类定义,但它被解释器当作一个对象来处理。
作为实例的对象是用foo = Foo()
之类的语句创建的,foo
是从object
类继承的对象。
>>> isinstance(foo, object)
True
这个类提供了对象需要的所有方法,例如__new__()
和__int__()
(new,init)。简而言之,前者用于创建类的新实例,后者在创建实例后调用,用于初始化值,就像使用Animal
一样。
事实上,所有东西都是一个对象,这也意味着我们可以做一些有趣的代码,比如
>>> class Foo:
... var = 'hello'
...
>>> foo = Foo()
>>> foo.var
'hello'
>>> foo.other_var = 'world'
>>> foo.other_var
'world'
>>> Foo.other_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'other_var'
>>> Foo.var
'hello'
>>>
在这里,我在运行时为对象添加了一个属性。该属性将在foo
中以单播方式存在,类本身或任何其他实例都没有该属性。这被称为实例变量和类变量。
希望这一切对你来说都有意义。
TL;博士
在Python中,所有的东西(类定义、函数、模块等)都被解释器当作对象来处理。因此,"一切"都是一个实例。