pythonjam無法執行 python的self

2021-10-13 06:41:54 字數 4861 閱讀 2991

python中的類和例項

物件導向最重要的概念就是類(class)和例項(instance)

類是抽象的模板,比如學生這個抽象的事物,可以用乙個student類來表示。

而例項是根據類建立出來的乙個個具體的「物件」,每乙個物件都從類中繼承有相同的方法,但各自的資料可能不同。

1、以student類為例,在python中,定義類如下:

class student(object):

pass

(object)表示該類從哪個類繼承下來的,object類是所有類都會繼承的類。

2、例項:定義好了類,就可以通過student類建立出student的例項,建立例項是通過類名+()實現:

student = student()

3、由於類起到模板的作用,因此,可以在建立例項的時候,把我們認為必須繫結的屬性強制填寫進去。這裡就用到python當中的乙個內建方法__init__方法,例如在student類時,把name、score等屬性綁上去:

class student(object):

def __init__(self, name, score):

self.name = name

self.score = score

這裡注意:

(1)、__init__方法的第一引數永遠是self,表示建立的類例項本身,因此,在__init__方法內部,就可以把各種屬性繫結到self,因為self就指向建立的例項本身。

(2)、有了__init__方法,在建立例項的時候,就不能傳入空的引數了,必須傳入與__init__方法匹配的引數,但self不需要傳,python直譯器會自己把例項變數傳進去

>>>student = student("hugh", 99)

>>>student.name

"hugh"

>>>student.score

另外,這裡self就是指類本身,self.name就是student類的屬性變數,是student類所有。而name是外部傳來的引數,不是student類所自帶的。

故,self.name = name的意思就是把外部傳來的引數name的值賦值給student類自己的屬性變數self.name。

4、和普通數相比,在類中定義函式只有一點不同,就是第一引數永遠是類的本身例項變數self,並且呼叫時,不用傳遞該引數。

除此之外,類的方法(函式)和普通函式沒啥區別,你既可以用預設引數、可變引數或者關鍵字引數(*args是可變引數,args接收的是乙個tuple,**kw是關鍵字引數,kw接收的是乙個dict)。

5、既然student類例項本身就擁有這些資料,那麼要訪問這些資料,就沒必要從外面的函式去訪問,而可以直接在student類的內部定義訪問資料的函式(方法),這樣,就可以把」資料」封裝起來。這些封裝資料的函式是和student類本身是關聯起來的,稱之為類的方法

class student(object):

def __init__(self, name, score):

self.__name = name

self.__score = score

def print_score(self):

print "%s: %s" %(self.__name,self.__score)

改完後,對於外部**來說,沒什麼變動,但是已經無法從外部訪問例項變數.__name和例項變數.__score了:

>>> student = student('hugh', 99)

>>> student.__name

traceback (most recent call last):

file "", line 1, in

attributeerror: 'student' object has no attribute '__name'

這樣就確保了外部**不能隨意修改物件內部的狀態,這樣通過訪問限制的保護,**更加健壯。

但是如果外部**要獲取name和score怎麼辦?可以給student類增加get_name和get_score這樣的方法:

class student(object):

def get_name(self):

return self.__name

def get_score(self):

return self.__score

如果又要允許外部**修改score怎麼辦?可以給student類增加set_score方法:

class student(object):

def set_score(self, score):

self.__score = score

需要注意的是,在python中,變數名類似__***__的,也就是以雙下劃線開頭,並且以雙下劃線結尾的,是特殊變數,特殊變數是可以直接訪問的,不是private變數,所以,不能用__name__、__score__這樣的變數名。

有些時候,你會看到以乙個下劃線開頭的例項變數名,比如_name,這樣的例項變數外部是可以訪問的,但是,按照約定俗成的規定,當你看到這樣的變數時,意思就是,「雖然我可以被訪問,但是,請把我視為私有變數,不要隨意訪問」。

封裝的另乙個好處是可以隨時給student類增加新的方法.

同樣的,方法可以直接在例項變數上呼叫,不需要知道內部實現細節.

self

(1)、self代表類的例項,而非類。

class test:

def ppr(self):

print(self)

print(self.__class__)

t = test()

t.ppr()

執行結果:

從上面的例子中可以很明顯的看出,self代表的是類的例項。而self.__class__則指向類。

注意:把self換成this,結果也一樣,但python中最好用約定俗成的self。

(2)、self可以不寫嗎?

在python直譯器的內部,當我們呼叫t.ppr()時,實際上python解釋成test.ppr(t),也就是把self替換成了類的例項。

class test:

def ppr():

print(self)

t = test()

t.ppr()

#################執行結果###################

traceback (most recent call last):

file "cl.py", line 6, in

t.ppr()

typeerror: ppr() takes 0 positional arguments but 1 was given

ppr在定義時沒有引數,但是我們執行時強行傳了乙個引數。

由於上面解釋過了t.ppr()等同於test.ppr(t),所以程式提醒我們多傳了乙個引數t。

這裡實際上已經部分說明了self在定義時不可以省略。

如果我們的定義和呼叫時均不傳類例項是可以的,這就是類方法。

class test:

def ppr():

print(__class__)

test.ppr()

############## 執行結果:############

(3)、在繼承時,傳入的是哪個例項,就是那個傳入的例項,而不是指定義了self的類的例項。

class parent:

def pprt(self):

print(self)

class child(parent):

def cprt(self):

print(self)

c = child()

c.cprt()

c.pprt()

p = parent()

p.pprt()

##############執行結果####################

解釋:執行c.cprt()時--------------------------指的是child類的例項。

執行c.pprt()時--------------------------等同於child.pprt(c),所以self指的依然是child類的例項,由於self中沒有定義pprt()方法,所以沿著繼承樹往上找,發現在父類parent中定義了pprt()方法,所以就會成功呼叫。

(4)、在描述符類中,self指的是描述符類的例項

class desc:

def __get__(self, ins, cls):

print('self in desc: %s ' % self )

print(self, ins, cls)

class test:

x = desc()

def prt(self):

print('self in test: %s' % self)

t = test()

t.prt()

t.x#################執行結果###################

self in test: <__main__.test object at>

self in desc: <__main__.desc object at>

desc類中定義的self不是應該是呼叫它的例項t嗎?怎麼變成了desc類的例項了呢?

因為這裡呼叫的是t.x,也就是說是test類的例項t的屬性x,由於例項t中並沒有定義屬性x,所以找到了類屬性x,而該屬性是描述符屬性,為desc類的例項而已,所以此處並沒有頂用test的任何方法。

那麼我們如果直接通過類來呼叫屬性x也可以得到相同的結果。

下面是把t.x改為test.x執行的結果:

self in test: <__main__.test object at>

self in desc: <__main__.desc object at>

<__main__.desc object at> none

解決python便攜版無法直接執行py檔案的問題

關聯 windows下無字首程式設計客棧直接執行.py檔案 關聯 便攜版python無法直接執行python指令碼的問題 症狀 直接執行py指令碼發現無法傳遞引數。在python便攜版可正常使用的情況下,python sqlmap.py u 可正常使用 指定py檔案使用python.exe開啟時,直...

如何執行py檔案

配置 win10系統 python 3.7 下面是乙個簡單的py檔案 配置系統環境變數 開啟系統環境變數介面,找到path,點編輯,新建python的安裝路徑 不含python.exe 新建批處理命令檔案 用文字編輯器 這裡notepad 寫,儲存為.bat即可。編碼使用ansi,否則雙擊它也打不開...

ubuntu 中執行 py 檔案

ubuntu 中執行 py 檔案 先將終端所在路徑切換到python指令碼檔案的目錄下 然後給指令碼檔案執行許可權,一般755就ok,如果完全是自己的私人電腦,也不做伺服器什麼的,給777的許可權問題也不大 具體許可權含義參考chmod指令的介紹,就不贅述了 chmod 755 py 然後執行。如果...