天天看點

Python程式設計:面向對象深入

基礎知識

程式設計:文法+資料結構+算法

程式設計範式:

面向過程,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)      

參考文章:

  1. 全面深入了解 Python 面向對象