代码如下:
# -*- coding:gb2312 -*-
class CarStore(object):
def order(self,car_type):
return Factory.select(car_type)
class Factory(object):
def select(car_type): #为什么这个地方的方法,没有self参数也可以运行?
if car_type == "索纳塔":
return Suonata()
elif car_type == "名图":
return Mingtu()
else:
print("没有您要的车型!")
class Car(object):
def move(self):
print("车在移动...")
def music(self):
print("正在播放音乐...")
def stop(self):
print("车在停止...")
class Suonata(Car):
def __init__(self):
print("索纳塔")
class Mingtu(Car):
def __init__(self):
print("名图")
car_store = CarStore()
suonata = car_store.order("索纳塔")
#car.move()
#car.music()
#car.stop()
suonata.move()
执行结果:
这段代码本身是没有问题,可以执行的。
我的疑问是,为什么第七行代码def select(car_type): 这个地方明明没有self,也可以执行?我记得我在学类的时候,被教育实例方法里面每个方法都必须加上一个self的参数,这里居然没有,然后我在这个地方加上了self反而出错了,如下图:
结果反而运行出错:
为什么会这样?
你是不是用的python3?
在python3中,如果成员函数不加self,则代表该函数是静态成员函数,可以直接使用“类名.函数名(参数)”的形式直接调用。
但是如果你加了self,则这个函数为类的成员函数,在其他调用类中必须这样调用:“类名.函数名(self,参数)”,或者在调用类类中实现一个实例,“实例名.函数名(参数)。
python3是上述这样,我的测试,在python2中不是。
你在select函数中加了self,但是在 CarStore::order()中调用却使用“类名.函数名(参数)”的形式,所以不正确。你在CarStore::order()调用时改为“类名.函数名(self,参数)”或者在CarStore::order()实现一个实例,使用“实例名.函数名(参数)“这样的形式试试。
昨晚看到的,太晚了,所以今天早上测试的。
self
不是魔法,改成什么名字都可以的
不一定非要
self
雷雷
按这个写法,
select
是对象方法,调用需要关联一个实例Factory()
。调用时对象实例是与第一个参数car_type
绑定。这个参数名一般约定为self
但是,不要求。你需要明白以下两种调用方式是不同的:
第一种方式,用实例对象去调用,第一个参数
car_type
自动与实例对象f
绑定;第二种方式,用类去调用,第一个参数(
car_type
)没有绑定;你需要自己绑定才能不出错——也就是你传进去的car_type
:Factory.selct(car_type)
这行。但是,当你加上
self
后,这个函数有两个参数,但是你只绑定了car_type
,也就是绑定到第一个参数self
,第二个没有值,必然就出错了。这里你要做的其实是将
select
实现成类方法:那么,以
Factory.select(car_type)
调用时,cls
自动绑定到Factory
,而car_type
则绑定到car_type
。以上,无论是
self
还是cls
,都只是约定的名字而已,起作用的是Python的类-对象-方法模型。建议可以看看《Python源码剖析》,至少要理解@classmethod是怎么工作的,要不然是写不好这类代码的。