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 然後執行。如果...