为什么在Python中x = Class()会创建一个新对象?
这是我学的第一门编程语言,所以请多包涵。我在看书的时候进展得很好,但一提到面向对象编程(OOP),我就完全迷糊了。我专门买了一本关于Python中OOP的新书,但还是搞不懂基本概念。
一开始,我对“self”这个概念感到困惑,但我现在在更基础的层面上也迷失了。
为什么x = Class()会创建这个类的新实例?难道它不是应该只指向这个类吗?
如果我也写y = Class(),那为什么你不会得到两个不同的变量,它们却指向同一个东西,尽管我把它们定义成了同样的东西?为什么不使用像“Instantiate("新实例的名字") Class()”这样的语言呢?
我真的搞不懂这里发生了什么。
编辑:哇,很多人这么快就回答了!那么我是不是可以理解为这里的等号是任意的,就像编程中的同音词?(同形词?)为什么会选择这样的方式,这似乎不太直观。我不是在批评它,是不是有历史原因?底下有没有什么逻辑是初学者看不懂的?
5 个回答
你问:
为什么不使用像“Instantiate("新实例名称") Class()”这样的语言呢?
答案是,Python 就是这样的语言——只是它省略了多余的单词 Instantiate
,而是用一个等号来表示正在进行赋值。除了这个小小的(且没有意义的)语法差别,这两种语言是一样的。
虽然我喜欢你提到的语言中使用 Instantiate
这个关键词,因为它能很清楚地表达发生了什么,但我也认为 Python 的设计有几个优点:
- 它更简洁。
- 更清楚地表明正在进行赋值。
- 提供了一个更明显的地方来放置初始化新实例时需要的参数。
- 对于大多数来自 C 语言及其衍生语言的程序员来说,更加熟悉。
一旦你对多种不同的编程语言有了一定的经验,我希望你能和我一样欣赏 Python 设计者所做出的聪明决策,这些决策让(好的)Python 代码既清晰又极其简洁。当然,你也可能有不同的看法,在这种情况下,你会发现许多不同语言中有各种各样的语法,或者,也许你会觉得有必要自己开发一种语法。
当你写 x = Class()
的时候,其实是在创建一个新的对象,这个对象是类 Class
的一个实例,叫做 x
。这就是面向对象编程(OOP)的核心概念。
在类里面,self
这个变量用来指代属于这个特定对象的变量。
举个例子:
class Dog:
def __init__(self,name,type):
self.name = name
self.type = type
self.mood = "happy"
def change_mood(self):
if self.mood == "happy":
self.mood = "sad"
else:
self.mood = "happy"
dog1 = Dog("Adam","big")
dog2 = Dog("James","small")
dog1.change_mood()
>>> dog1.mood
"sad"
>>> dog2.mood
"happy"
你们应该学过函数,对吧?
类就像是能产生新对象的函数。Class()
这个意思是你在调用它,每次你调用它,都会得到一个新的对象。这就是类被调用时的作用。
x = Class
和 x = Class()
是完全不同的。前者只是给类起了个别名。
至于“为什么”,其实有时候能用函数代替类,或者用类代替函数是很方便的。比如,int()
这个函数其实根本不是一个函数;你只是在创建一个新的 int
对象。
至于 =
,这个就没什么好解释的了 :) 大多数编程语言用 a = b
来表示“把 b
的值存到 a
里”,而不是说 a
和 b
是相等的。这是历史原因吧。
你可以这样看到一个类的对象成员被创建:
class Foo(object):
def __new__(cls):
print 'new Foo'
return super(Foo, cls).__new__(cls)
def __init__(self):
print 'init Foo'
>>> foo=Foo()
new Foo
init Foo
在Python中,()
表示调用一个类(或者函数或方法)。对于一个类来说,这首先会调用new
,然后是__init__
。
对类本身的引用就是 Class
。写 Class()
是在 调用 这个类,这样会返回这个类的一个实例。
def foo():
return 42
print foo
print foo()
class Class(object):
pass
print Class
print Class()