【问题标题】:When is an "instance" being created?什么时候创建“实例”?
【发布时间】:2019-06-13 02:27:46
【问题描述】:

我一直在阅读有关使用 python 进行 OOP 的文章,特别是 this one

那篇文章的作者有一个描述,然后是一个代码示例:

实例化类的 Python 语法与函数相同 打电话

>>> b = int()
>>> type(b)
<type 'int'>

据此,我推断“实例”存在于执行时而不是之前。当您执行 type(b) 时,这就是类 int() 的实例。

但后来我读到了这个stack overflow answer

Instance是一个保存Object内存地址的变量。

这让我对这个词有点困惑。那么当我在执行时分配一个变量时,会创建“实例”吗?

最后这个explanation in 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");

Animal 对象允许腿的数量和声音 Animal 使对象的每个实例都被设置。在这种情况下, 所有三个实例(狮子、猫和狗)都有相同数量的腿, 但发出不同的声音。

谁能提供一个关于实例何时退出的明确定义?

【问题讨论】:

  • 我认为使用术语“变量”来定义“实例”是不正确的。您可以在不将对象绑定到名称的情况下实例化对象:int() 本身,没有赋值语句,是一个完全有效的 Python 程序。一个整数被实例化了,但是这里没有变量。
  • 您提供的每个示例都是真实的!我会说术语“实例”是一个抽象概念 - 对其进行严格定义并没有多大用处。您可以通过说它具有这三个特征/行为来很好地定义它。
  • Python documentation 说“创建一个新类会创建一种新类型的对象,允许创建该类型的新实例。”如果这有帮助。另外,“类实例化使用函数表示法。假设类对象是一个返回类的新实例的无参数函数。”
  • 你的问题的答案“所以当我在执行的那一刻分配一个变量时,“实例”被创建了吗?是是的'。这两件事都发生在那一刻。

标签: python concept


【解决方案1】:

我一直在阅读有关使用 python 进行 OOP 的文章,特别是 this one

那篇文章的作者有一个描述,然后是一个代码示例:

实例化类的 Python 语法与函数相同 打电话

>>> b = int()
>>> type(b)
<type 'int'>

又读了之前的那句话:

一旦你有了一个类,你就可以实例化它以获得该类型的具体对象(instance),即根据该类的结构构建的对象.

所以一个类的实例是一个以该类为类型的对象。

据此,我推断“实例”在执行时存在,并且 不是以前。

是的,正确。 “Instance”和“instance of”是 Python 中的运行时概念。

当您执行 type(b) 时,这是 类 int()。

不完全是。

这里的int实例在int()被调用时开始存在。1这个过程就是所谓的“实例化”和结果(由这个调用返回,在此示例中,然后分配给b) 是int 的“实例”。

但后来我读到了这个stack overflow answer

Instance是一个保存Object内存地址的变量。

哦,好吧,这不太正确。它是对象本身(该内存地址的值,如果你愿意的话)就是实例。几个变量可以绑定到同一个对象(因此是同一个实例)。甚至还有一个用于测试的运算符:is

>>> a = 5
>>> b = a
>>> a is b
True

这让我对这个词有点困惑。所以当我分配一个 执行时的变量“实例”是否创建?

不,那么实例是绑定到那个变量的。在 Python 中,将变量视为“值的名称”。因此,将对象绑定到变​​量意味着为该对象赋予该名称。正如我们在上面看到的,一个对象可以有多个名称。

您可以使用实例而不将其分配给任何变量,即不命名它,例如通过将其传递给函数:

>>> print(int())
0

最后,explanation in 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");

Animal 对象允许腿的数量和声音 Animal 使对象的每个实例都被设置。在这种情况下, 所有三个实例(狮子、猫和狗)都有相同数量的腿, 但发出不同的声音。

不幸的是,ComputerHope 上的解释可能会让大多数读者感到困惑,而不是帮助他们。首先,它将术语“类”和“对象”混为一谈。他们的意思不一样。类是一种对象的模板。对象类型的对象和模板不是同一个概念,就像 cookie 切割器与 cookie 不同一样。

当然,[为了理解] 在 Python 中,类 (特殊,但不是太特殊)对象(type 类型)和 JavaScript 中的对象并没有特别的帮助在引入class 概念之前,习惯上使用普通对象作为其他对象的模板。 (后一种方法被称为“prototype based面向对象”或“基于原型的继承”。相比之下,大多数其他面向对象的语言,包括 Python,都使用基于类的面向对象/基于类的继承。我不太懂确定带有 class 关键字的现代 ECMAScript 属于哪个类别。)

谁能真正提供一个明确的实例定义?

就像我写得更远: 一个类的实例是一个对象,它具有该类作为其类型

因此,“实例”始终是“of”事物的“实例”。这也回答了标题中问题的语言理解

什么时候应该称它为“实例”?

当您想将其称为“实例of”某事物(通常属于某个类)时,应将其称为“实例”。


1 我还没有说出全部真相。试试这个:

>>> a = int()
>>> b = int()
>>> a is b
True

等等什么? int 的两次调用不应该各自返回新实例,从而返回两个不同的实例吗?

大多数类型都会发生这种情况,但一些内置类型是不同的,int 就是其中之一。 CPython 实现的制造者知道小整数被大量使用。因此,他们让 CPython 一直创建新的,他们只是让它在每次需要相同的值时重复使用相同的整数(相同的对象/实例)。由于 Python 整数是不可变的,这通常不会导致任何问题,并且在计算密集型程序中节省了大量内存和对象创建时间。

Python 标准允许实现进行这种优化,但 AFAIK 并不要求它们这样做。所以这应该被认为是一个实现细节,你的程序逻辑不应该依赖于此。 (不过,您的性能优化可能依赖它。)

【讨论】:

  • 感谢您的详细解释,我实际上想知道实例是何时“创建”的,当然这是在执行时刻而不是变量赋值。因此,第一个链接中的作者正确解释了它。很明显,至少在 python 和这个例子中 int() 执行比赋值先发生,所以仍然是函数执行。
【解决方案2】:

一般在OOP中

类和对象是面向对象的两个主要方面 编程。一个类创建一个新类型,其中对象是 班级。

正如here 解释的那样。

因此,每次创建对象时,它都称为实例。

Python 在这个概念上没有任何区别,但是与其他语言(例如 Java)有些不同。

事实上,在 Python 中一切都是一个对象,甚至类本身也是如此。

以下是其工作原理的简要说明:

考虑到这个sn-p:

>>> class Foo:
...     pass
... 
>>> type(Foo)
<type 'type'>
>>> 

Foo 类是 type 类型,它是 Python 中所有 classes 的元类 (然而,“旧”和“新”类之间存在区别,更多的是 hereherehere)。

Class type 是一个类,是它自己的一个实例:

>>> isinstance(type, type)
True

所以Foo 尽管是一个类定义,但仍被解释器视为对象。

作为实例的对象是通过 foo = Foo() 之类的语句创建的,foo 是一个从 object 类继承的对象。

>>> isinstance(foo, object)
True

这个类提供了一个对象需要的所有方法,例如__new__()__int__()newinit)。简而言之,前者用于创建类的新实例,后者在实例创建后调用,用于初始化值,就像您对 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 中,类本身或任何其他实例都不会拥有它。 这称为Instance variable and class variable

希望这一切对你有意义。

TL;DR

在 Python 中,所有内容(类定义、functions、模块等)都被解释器视为对象。因此“一切”都是一个实例。

【讨论】:

  • 我认为,为了简单起见,在回复不知道实例是什么的人时,您可以删掉很多关于 python 类中的对象的细节等等开。
猜你喜欢
  • 1970-01-01
  • 2018-03-02
  • 2014-09-14
  • 2010-11-08
  • 2011-05-31
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多