程式小白 問關於python當中類別的方法的參數問題
欧阳克
欧阳克 2017-06-22 11:52:02
0
4
955

程式碼如下:

#
# -*- 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反而出錯了,如下圖:

結果反而運行出錯:

#為什麼會這樣?

#
欧阳克
欧阳克

温故而知新,可以为师矣。 博客:www.ouyangke.com

全部回覆(4)
巴扎黑

你是不是用的python3?
在python3中,如果成員函數不加self,則代表函數是靜態成員函數,可以直接使用「類別名稱.函數名(參數)」的形式直接呼叫。
但是如果你加了self,則這個函數為類的成員函數,在其他調用類中必須這樣調用:“類名.函數名(self,參數)”,或者在調用類類中實現一個實例,“實例名.函數名(參數)。

python3是上述這樣,我的測試,在python2中不是。

你在select函數中加了self,但是在 CarStore::order()中呼叫卻使用「類別名稱.函數名稱(參數)」的形式,所以不正確。你在CarStore::order()呼叫時改為「類別名稱.函數名稱(self,參數)」或在CarStore::order()實作一個實例,使用「實例名稱.函數名稱(參數)「這樣的形式試試。

昨晚看到的,太晚了,所以今天早上測試的。

三叔

self 不是魔法,
改成什麼名字都可以的

不一定要 self

为情所困

雷雷

Ty80
class Factory(object):        
    def select(car_type):
        if car_type == "索纳塔":
            return Suonata()
        elif car_type == "名图":
            return Mingtu()
        else:
            print("没有您要的车型!")

按這個寫法,select是物件方法,呼叫需要關聯一個實例Factory()。呼叫時物件實例是與第一個參數car_type綁定。這個參數名一般約定為self但是,不要求。

你需要明白以下兩種呼叫方式是不同的:

f = Factory()
f.select(xxx)

Factory.select(xxx)

第一種方式,用實例物件去調用,第一個參數car_type自動與實例物件f綁定;
第二種方式,用類別去調用,第一個參數(car_type)沒有綁定;你需要自己綁定才能不出錯-也就是你傳進去的car_typeFactory.selct(car_type)這行。

但是,當你加上self後,這個函數有兩個參數,但是你只綁定了car_type,也就是綁定到第一個參數self,第二個沒有值,必然就出錯了。

這裡你要做的其實是將select實作成類方法:

class Factory(object):   

    @classmethod     
    def select(cls, car_type):
        if car_type == "索纳塔":
            return Suonata()
        elif car_type == "名图":
            return Mingtu()
        else:
            print("没有您要的车型!")

那麼,以Factory.select(car_type)呼叫時,cls自動綁定到Factory,而car_type則綁定到car_type

以上,無論是self還是cls,都只是約定的名字而已,起作用的是Python的類-對象-方法模型。

建議可以看看《Python原始碼剖析》,至少要理解@classmethod是怎麼運作的,要不然是寫不好這類程式碼的。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板