實例變量 & 類變量
class Role(object):
# <類變量> = var
n = 100
n_list = []
name = 'hahaha'
def __init__(self, var):
# self.<實例變量> = var
self.name = var
>>>r1 = Role(var='lalala')
>>>r1.name
lalala
>>>Role.name
hahaha
>>>r2 = Role('lex')
>>>r2.n
100
>>>r1.n = 200
>>>r1.n
200
>>>r2.n
100
# 其實在r1的內(nèi)存里創(chuàng)建了變量 n=200,類變量沒動
# r1,r2,Role 都公用一個內(nèi)存變量 n_list
>>>r1.n_list.append("from r1")
>>>r2.n_list.append("from r2")
>>>r2.n_list
["from r1","from r2"]
>>>Role.n_list
["from r1","from r2"]
析構(gòu)函數(shù)
在實例釋放、銷毀的時候自動執(zhí)行
del var 啟動 __del__(self)方法
摘掉門牌號,自動回收機(jī)制刪除內(nèi)存
私有方法、私有屬性
加倆下劃線:self.life_value ---> self.__life_value
外界無法直接訪問,可以內(nèi)部定義一個方法訪問
類的封裝
封裝數(shù)據(jù)的函數(shù)是和Student類本身是關(guān)聯(lián)起來的,我們稱之為類的方法。
簡單的說,將外部函數(shù)內(nèi)部化為類的方法,就是封裝。
新式類 & 經(jīng)典類
""" Author: Dr.Ch """
# class People: ## 經(jīng)典類寫法
class People(object): # 新式類 ## object是個基類
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print("%s is eating..." % self.name)
def talk(self):
print("%s is talking..." % self.name)
def sleep(self):
print("%s is sleeping..." % self.name)
class Relation(object): # 給人加上社交屬性
def make_friends(self, obj): # obj 是 其他人,尚未實例化的
print("%s is making friends with %s" % (self.name, obj.name))
class Man(People, Relation): # 注釋1
# 為了增加子類屬性,需要重構(gòu) __init__()
def __init__(self, name, age, money): # 增加屬性:男人出生就有錢
# 把父類的屬性拿過來
People.__init__(self, name, age) # 經(jīng)典類寫法
self.money = money
print("%s 一出生就有 %s money" % (self.name, self.money))
def whoring(self): # 定義子類新方法
print("%s is whoring..." % self.name)
def sleep(self):
print("man is sleeping...") # 更改父類方法
def talk(self):
People.talk(self) # 直接調(diào)用父類方法
def eat(self):
People.eat(self)
print("man is eating...") # 在父類方法上增加新功能
class Woman(People, Relation):
def __init__(self, name, age, height, big_breast=True):
# 另一種高級的方法繼承父類,代替 line32 的語法
super(Woman, self).__init__(name, age) # 新式類寫法 ## 注釋2
self.height = height
self.big_breast = big_breast
def get_birth(self):
print("%s is born a baby..." % self.name)
print("\n--------- 多繼承 -----------")
m3 = Man("Jon", 25, 2000)
w3 = Woman("Maria", 22, 170, False)
m3.make_friends(w3)
print("\n--------- women -----------")
w1 = Woman("alex", 22, 162)
w1.get_birth()
print("\n--------- men -----------")
m1 = Man("lex", 23, 20)
m1.whoring()
m1.sleep()
m1.talk()
m1.eat()
print("\n--------- men 繼承 -----------")
m2 = Man("clark", 24, 100)
print("\n--------- women 繼承 -----------")
w2 = Woman("lana", 21, 165)
"""
注釋1:Man的實現(xiàn) 先在Man里面執(zhí)行__init__()生成 name ,再繼承Relation的方法,所以name已經(jīng)有了
不是在People里面執(zhí)行__init__(),所以 Man(People,Relation)繼承順序無影響。
如果沒有自己的構(gòu)造方法,應(yīng)該去執(zhí)行父類的__init__(),然而依然沒有報錯(Relation,People),
因為make_friends()還沒有執(zhí)行。
……總之按照從左到右順序繼承。(見視頻30分鐘處)
對象生成,先實例化,多繼承的時候,從左到右: SubClass(Class1,Class2,...,ClassN):
先執(zhí)行 SubClass 的 構(gòu)造函數(shù)__init__(),如果沒有構(gòu)造函數(shù),則
執(zhí)行 Class1 的 構(gòu)造函數(shù),如果 Class1 也沒有 構(gòu)造函數(shù),則
執(zhí)行 Class2 的 構(gòu)造函數(shù),…… 以此類推。重點是,只繼承一個就結(jié)束。
—— 關(guān)于廣度優(yōu)先、深度優(yōu)先見視頻6.9 10分鐘左右——(面試必備)
A,B(A),C(A),D(B,C)
py2 是深度優(yōu)先:D先繼承B,再繼承A,最后繼承C
py3 經(jīng)典類和新式類都是統(tǒng)一按照廣度優(yōu)先來繼承的:D先繼承B,再繼承C,最后繼承A
注釋2:與 People.__init__(self, name, age) 相比優(yōu)點在于,
super(Woman,self).__init__(name, age) 不用寫父類名 People,
如果有一天 People 名字改了,只需要改一次 line50 處
另外,有利于多繼承。
經(jīng)典類 和 新式類 區(qū)別主要體現(xiàn)在 多繼承 上。
"""
--------- 多繼承 -----------
Jon 一出生就有 2000 money
Jon is making friends with Maria
--------- women -----------
alex is born a baby...
--------- men -----------
lex 一出生就有 20 money
lex is whoring...
man is sleeping...
lex is talking...
lex is eating...
man is eating...
--------- men 繼承 -----------
clark 一出生就有 100 money
--------- women 繼承 -----------
Process finished with exit code 0
靜態(tài)方法
@staticmethod 靜態(tài)方法 跟 類 的關(guān)系切斷了,變成了普通的函數(shù)
唯一與類的關(guān)聯(lián)就是,如果要調(diào)用,必須通過類名(實例名)調(diào)用
普通的 類的方法 需要傳入self參數(shù)。
(如果非要傳self參數(shù),需要再把實例傳進(jìn)去,這就失去靜態(tài)方法的意義了)
用處:把類變成一個工具包組合。
類方法
@classmethod 類方法只能訪問類變量,不能訪問實例變量(似乎沒怎么用過)
場景:強(qiáng)制使用類屬性,實例變量改了沒用,比如禁止改國籍。
屬性方法
@property 導(dǎo)致方法不可調(diào)用
效果:把一個方法變成一個靜態(tài)屬性,不再可以加()調(diào)用,不能傳參數(shù)了
作用:隱藏實現(xiàn)細(xì)節(jié),只給用戶輸出結(jié)果。
查看類方法的說明文檔
import pandas as pd
df = pd.DataFrame(data)
# 查看DataFrame類在哪個模塊里:
>>>df.info()
>>>
<class 'pandas.core.frame.DataFrame'>...
# 查看info()方法說明文檔:
print(pd.DataFrame.info.__doc__)
df 的各種操作
df.sum() # 按字段求和