class base:
def __init__(self,num):
self.num = num
def func(self):
print(self.num)
class foo(base):
pass
obj = foo(123)
obj.func() #輸出 : 123
執行的時候foo會去找父類,然後num被賦值123傳遞進去,然後調用func是foo父類下的,打印123出來.
class base:
def __init__(self,num):
self.num =num
def func1(self):
print(self.num)
class foo(base):
def func1(self):
print("foo. func1",self.num)
obj = foo(123)
obj.func1() #輸出: foo. func1 123
執行時首先運行obj = foo的,然後執行foo類,將123丟給了base,base執行下面的__init__,然後將123賦值給self,此時變量存儲在foo的局部空間中,因爲base是父類,子類可以調用父類變量,再向下運行func1,然後執行foo的func1,輸出foo . func 123.
class base:
def __init__(self,num):
self.num =num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print("base func2")
class foo(base):
def func2(self):
print("foo. func2")
obj = foo(123)
obj.func1() #輸出: 123 \n foo. func2
調用obj.func1的時候,會找父類調用了func1,輸出了num的值,也就是123,然後又開始執行了func2,self是obj,所以是obj,func2,此時子類裏面有func2,所以執行輸出了foo.func2
誰調用了類,類後面的括號放的就是誰,傳遞給類的時候self也就是調用的變量
self訪問順序:永遠先找自己類的再去找父類
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print(111, self.num)
class Foo(Base):
def func2(self):
print(222, self.num)
lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
obj.func2() #輸出: 111 1 \n 111 2 \n 222 3
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print(111, self.num)
class Foo(Base):
def func2(self):
print(222, self.num)
lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
obj.func1() #輸出:
#1
#111 1
#2
#111 2
#3
#222 3
前面兩個傳遞的是base,所以調用base裏面的func2,後面傳遞了foo,所以調用了foo的func2.
特殊成員
帶雙下劃綫的,不需要自己定義的,在特殊場景會被自動的調用.
1. 類名() 會⾃動執⾏__init__()
2. 對象() 會⾃動執⾏__call__()
3. 對象[key] 會⾃動執⾏__getitem__()
4. 對象[key] = value 會⾃動執⾏__setitem__()
5. del 對象[key] 會⾃動執⾏ __delitem__()
6. 對象+對象 會⾃動執⾏ __add__()
7. with 對象 as 變量 會⾃動執⾏__enter__ 和__exit__
8. 打印對象的時候 會⾃動執⾏ __str__
9. ⼲掉可哈希 __hash__ == None 對象就不可哈希了.
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
f = foo() #自動執行 __init__ #輸出: 初始化操作,在創建對象的時候自動調用
#f.__init__() #輸出:初始化操作,在創建對象的時候自動調用
# collable #判斷是否可被調用,是否可以加()
print(callable(f)) #輸出:Flash,因爲對象沒有加(),如果需要加括號運行,需要在類裏面寫 __call__
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
def __call__(self, *args, **kwargs):
print("我是對象加括號")
print(callable(foo)) #輸出 : True
f = foo() #輸出:初始化操作,在創建對象的時候自動調用
f() # 輸出:我是對象加括號 默認對象f調用了__call__
列表[ ] 調用了getitem
lst = ["劉老六","吳老五","齊老七"]
print(lst[2]) #輸出: 齊老七 ,此時,[]會自動調用__getitem__()
#
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
def __getitem__(self, item):
print("item=",item)
return "haha"
f = foo()
print(f["吳老五"]) #自動調用item,會把值交給item #輸出:item= 吳老五 \n haha
#所有元組,字典,加中括號都是調用了__item__
添加操作調用了__setitem__
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
def __setitem__(self, key, value):
print("key = ",key)
print("value = ",value)
f = foo()
f['lll'] = "劉老六" #輸出:key = lll \n value = 劉老六
enter和exit
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
#with 對象
def __enter__(self):
print("調用了enter")
#當代碼執行完畢,最後執行這裏
def __exit__(self, exc_type, exc_val, exc_tb):
print("調用了exit")
f = foo()
with f:
print("我是with")#輸出:調用了enter \n 我是with \n 調用了exit
#會自動調用exit退出,所以with open()的時候不用管文件的關閉,執行結束自動就關閉了
#可用來在函數執行前或執行後添加執行函數,類似於裝飾器
特殊對象還有很多不一一列舉,可以自己用的時候查看
new
class foo:
def __init__(self):
print("初始化操作,在創建對象的時候自動調用")
#init是初始化方法,__new__纔是真正的構造方法,可以開闢內存,每個類之少都有一個new和init
def __new__(cls, *args, **kwargs):
print("調用了new")
return object.__new__(cls)
f = foo()
面向對象執行流程
加載對象,給類創建一個名稱空間,主要存放類變量,類方法
創建對象,先找類,根據類來開闢內存,執行類中的new,執行init返回對象
str
class foo:
def __init__(self,name,age,num):
self.name = name
self.num = num
print("初始化操作,在創建對象的時候自動調用")
def __str__(self):
return f"{self.name},{self.num}"
f = foo("劉老六",88,"88765")
print(f) #輸出:劉老六,88765
#沒有str輸出一串內存地址