程式碼如下:
## -*- 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是上述這樣,我的測試,在python2中不是。在python3中,如果成員函數不加self,則代表函數是靜態成員函數,可以直接使用「類別名稱.函數名(參數)」的形式直接呼叫。
但是如果你加了self,則這個函數為類的成員函數,在其他調用類中必須這樣調用:“類名.函數名(self,參數)”,或者在調用類類中實現一個實例,“實例名.函數名(參數)。
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是怎麼運作的,要不然是寫不好這類程式碼的。