何时创建"instance"?



我一直在阅读关于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中,所有的东西(类定义、函数、模块等)都被解释器当作对象来处理。因此,"一切"都是一个实例。

最新更新