基礎知識
程式設計:文法+資料結構+算法
程式設計範式:
面向過程,step by step top-down language
面向對象oop,世界萬物,皆可分類,皆為對象
特性
class –執行個體化–> object
執行個體化:把類變成具體對象的過程
封裝:資料隐藏
把一些功能的實作細節不對外暴露
繼承:代碼複用
組合
單繼承
多繼承
py2
- 經典類:深度優先來繼承的
- 新式類:廣度優先來繼承的 class Foo(object)
py3
- 經典類和新式類都是按照廣度優先來繼承的
多态:接口重用
一個接口,多種實作
類:
1. 屬性:
1. 類變量 大家共用屬性,節省記憶體開銷
2. 執行個體變量(靜态屬性):作用域是執行個體本身
3. 私有屬性 __開頭
2.方法(動态屬性)
1. 構造函數:init 執行個體化時做類的初始化工作
2. 析構函數:del 釋放,銷毀對象時執行,通常用于收尾工作,如關閉資料庫連接配接,關閉臨時檔案
3. 私有方法 __開頭
4. 靜态方法:staticmethod與類沒什麼關系,隻是名義上資料
5. 類方法:classmethod 隻能通路類變量,不能通路執行個體變量
6. 屬性方法:property 把一個方法變成一個靜态屬性
程式設計原則:
1、不寫重複代碼
2、代碼會經常變更,做到易讀,易改
對象執行個體化:
資料拷貝
方法不拷貝
object.method 相當于 class.method(object)
類屬性
class Dog(object):
count = 0 # 類變量
lst = []
def __init__(self, name): # 構造函數
self.name = name # 執行個體變量
self.__age = 0 # 私有屬性
def bark(self): # 方法
print("%s bark" % self.name)
def __del__(self): # 析構函數
print("%s del" % self.name)
# 執行個體化對象,并賦予執行個體變量,相當于局部變量
d1 = Dog("Tom")
d2 = Dog("Alex")
d3 = Dog("Jack")
# 調用對象方法
d1.bark() # Tom bark
d2.bark() # Alex bark
d3.bark() # Jack bark
# 修改類變量,相當于全局變量
d1.count = 12
d2.count = 12
d3.count = 12
print(Dog.count) #0 #類變量 沒有被修改
print(d1.count) #12
print(d1.count) #12
print(d1.count) #12
d1.lst.append("d1")
d2.lst.append("d2")
d3.lst.append("d3")
# 類變量 清單被修改了
print(Dog.lst) # ['d1', 'd2', 'd3']
print(d1.lst) # ['d1', 'd2', 'd3']
print(d2.lst) # ['d1', 'd2', 'd3']
print(d3.lst) # ['d1', 'd2', 'd3']
多态
class Animal(object):
count = 1
def __init__(self, name):
self.name = name
self.__color = None
def talk(self):
pass
@staticmethod # 靜态方法
def animal_talk(animal):
animal.talk()
@classmethod # 類方法
def animal_sleep(cls):
print(cls,cls.count)
@property # 屬性方法
def color(self):
return self.__color
@color.setter # 設定
def color(self, color):
self.__color = color
@color.deleter # 删除
def color(self):
del self.__color
class Cat(Animal):
def talk(self):
print("%s talking" % self.name)
class Dog(Animal):
def talk(self):
print("%s talking" % self.name)
cat = Cat("mimi")
dog = Dog("jiji")
Animal.animal_talk(cat)
Animal.animal_talk(dog)
Animal.animal_sleep()
print(dog.color)
dog.color = "red"
print(dog.color)
del dog.color
繼承
# class People: #經典類
class People(object): # 新式類
def __init__(self, name, age):
self.name = name
self.age = age
def sleep(self):
print("%s is sleeping" % self.name)
class Animal(object):
def drink(self):
print("%s drinking" % self.name)
class Man(People, Animal): # 多繼承
def __init__(self, name, age, money):
People.__init__(self, name, age)
# 等價于:super(Man, self).__init__(name, age) 新式類寫法
self.money = money
print("%s have money %s" % (name, money))
def work(self):
print("%s is working" % self.name)
def sleep(self): # 重載父類方法
People.sleep(self) # 調用父類方法
print("Man is sleeping")
class Woman(People):
def eat(self):
print("%s is eating" % self.name)
m = Man("Tom", 23, 2000)
w = Woman("Jack", 24)
m.sleep() # Tom is sleeping
m.work() # Tom is working
w.sleep() # Jack is sleeping
w.eat() # Jack is eating
m.drink() # Tom drinking
繼承順序
class A(object):
pass
# def __init__(self):
# print("init A")
class B(object):
def __init__(self):
print("init B")
class C(A):
pass
# def __init__(self):
# print("init C")
class D(B):
pass
# def __init__(self):
# print("init D")
class E(C, D):
pass
# def __init__(self):
# print("init E")
e = E()
# C -> A -> D -> B
類的特殊方法
class Dog(object):
"""類的描述資訊"""
def __init__(self,name):
self.name = name
self.data = {}
def __call__(self):
print("call")
def __str__(self): #列印時觸發
return self.name
def __getitem__(self, item): # 像字典一樣通路對象
print("getitem")
return self.data.get(item)
def __setitem__(self, key, value): # 設定值
print("setitem")
self.data[key] = value
def __delitem__(self, key): # 删除值
print("delitem")
del self.data[key]
print(Dog.__doc__) # 輸出類的描述資訊
dog = Dog("Tom")
print(dog.__module__) # 輸出子產品 __main__
print(dog.__class__) # 輸出類 <class '__main__.Dog'>
dog() # 對象() 括号觸發__call__ 方法
print(Dog.__dict__) #列印類所有屬性,不包括執行個體屬性
# {'__weakref__': <attribute '__weakref__' of 'Dog' objects>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__init__': <function Dog.__init__ at 0x00000000047B5BF8>,
# '__doc__': '類的描述資訊',
# '__call__': <function Dog.__call__ at 0x00000000047B5C80>,
# '__module__': '__main__'}
print(dog.__dict__) # 列印執行個體所有屬性,不包括類屬性
# {'name': 'Tom'}
print(dog)
dog["dog1"] = "dogA"
dog["dog2"] = "dogB"
dog["dog3"] = "dogC"
print(dog["dog1"])
print(dog["dog2"])
print(dog["dog3"])
print(dog.data)
del dog["dog1"]
del dog["dog2"]
del dog["dog3"]
print(dog.data)
類的本質
# python一切皆為對象,類類型也是對象 ,由type類執行個體化而來
# class Foo():
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def talk(self):
# print("%s is talking" % self.name)
#
# f= Foo("Alex", 23)
# f.talk()
# 等價于:
def __init__(self, name, age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" % self.name)
Foo = type("Foo", (object,), {"__init__": __init__, "talk": talk})
f= Foo("Alex", 23)
f.talk()
元類
class Foo(object):
def __init__(self, name):
self.name = name
print("init")
def __new__(cls, *args, **kwargs):
print("new")
return object.__new__(cls) # 繼承父類的 new 方法
f = Foo("Tom")
# new
# init
# 元類metaclass:就是類的類,所有類都源自type
print(f.__class__) # <class '__main__.Foo'>
print(Foo.__class__) # <class 'type'>
a = 5
print(a.__class__) #<class 'int'>
print(a.__class__.__class__) #<class 'type'>
b = "name"
print(b.__class__) # <class 'str'>
print(b.__class__.__class__) # <class 'type'>
def foo(): pass
print(foo.__class__) #<class 'function'>
print(foo.__class__.__class__) #<class 'type'>
反射
# 反射函數
"""
hasattr() 檢查成員
getattr() 擷取成員
setattr() 設定成員
delattr() 删除成員
"""
class Foo(object):
def __init__(self):
self.name = "Tom"
def eat(self):
print("eating")
def talk():
print("talking")
f= Foo()
choice = input("輸入>>")
if hasattr(f, choice): # 判斷對象是否有名稱為choice 的屬性
delattr(f, choice) # 删除對象屬性
# func = getattr(f, choice) # 通過字元串擷取對象函數位址
# func()
else:
setattr(f, "talk", talk) # 動态給對象增加新方法
f.talk()
setattr(f, "age", 23) #給對象增加靜态屬性
print(f.age)
print(f.name)
參考文章: