1. 程式人生 > >python類與類之間的關系

python類與類之間的關系

self compute xxx put 高級 pin %s 形式 什麽

在面向對象中,類和類之間也可以產生相關的關系
類中的關系: 依賴關系是最輕的,最重的是繼承關系,關聯關系是比較微妙的

依賴關系
執行某個動作的時候,需要xxx來幫助完成這個操作,此時的關系是最輕的.
隨時可以更換另外一個東西來完成此操作

class Person:
    def f1(self,tools):     # 通過參數的傳遞把另外一個類的對象傳遞進來
        tools.run()
        print(皮一下很開心)
class Computer:
    def run(self):
        print(電腦開機運行)
class Phone:
    
def run(self): print(手機開機) c = Computer() a = Phone() p = Person() p.f1(a) #把Phone類的對象a傳遞給Person的f1方法作為參數 結果 手機開機 皮一下很開心 事例二 植物大戰僵屍 class Plant: def __init__(self,hp,ad): self.hp = hp self.ad = ad def attack(self,js): print(植物攻擊僵屍) js.hp -= self.ad
print(f僵屍掉血{self.ad},剩余{js.hp}) class JiangShi: def __init__(self,hp,ad): self.hp = hp self.ad = ad def attack(self,zw): print(僵屍咬植物) zw.hp -= self.ad print(f植物掉血{self.ad},剩余{zw.hp}) zw = Plant(100,11) js = JiangShi(80,15) zw.attack(js) zw.attack(js) js.attack(zw) js.attack(zw) 結果 植物攻擊僵屍 僵屍掉血11,剩余69 植物攻擊僵屍 僵屍掉血11,剩余58 僵屍咬植物 植物掉血15,剩余85 僵屍咬植物 植物掉血15,剩余70

關聯關系
對象裏面包含對象

一對一關系
class Boy:
    def __init__(self,name,girFriend=None):
        self.name = name
        self.girFriend = girFriend
    def play(self):
        if self.girFriend:
            print(f{self.name}帶著他女朋友{self.girFriend.name}去吃飯)
        else:
            print(單身狗,還吃什麽飯)
    def movie(self):
        if self.girFriend:
            print(f{self.name}帶著他女朋友{self.girFriend.name}去看電影)
        else:
            print(單身狗,還看什麽電影)
class Girl:
    def __init__(self,name):
        self.name = name
b = Boy(劉昊然)
g = Girl(劉麗)
b.play()

b.girFriend = g
b.play()

g2 = Girl(王萌)
b.girFriend = g2
b.movie()


一對多關系
self.teach_list = [t1,t2,...]
class School:
    def __init__(self,name):
        self.teach_list = []
    def zhaopin(self,teach):
        self.teach_list.append(teach)
    def shangke(self):
        for i in self.teach_list:
            i.work()
class Teacher:
    def __init__(self,name):
        self.name = name
    def work(self):
        print(f{self.name}在上課)
lnh = School(測試)
t1 = Teacher(趙老師)
t2 = Teacher(劉老師)
lnh.zhaopin(t1)
lnh.zhaopin(t2)
lnh.shangke()
結果
趙老師在上課
劉老師在上課

繼承關系

class Base:         #父類又叫基類又叫超類
    def chi(self):
        print(吃飯)
class Foo(Base):    #子類又叫派生類,這個類繼承了Base類,Foo類是對Base的一個擴展
    def he(self):
        print(喝水)
f = Foo()
f.chi()
f.he()
print(hash(Foo))    #默認類和創建的對象都是可哈希的
print(hash(Foo()))
結果
吃飯
喝水
-9223371912599947772
-9223371912597968945

去掉可哈希
__hash__ = None
class Base:
    def chi(self):
        print(吃飯)
class Foo(Base):
    __hash__ = None     # 當前類的對象不可哈希
    def he(self):
        print(喝水)
f = Foo()
f.chi()
f.he()
print(hash(Foo))    # 類名永遠可哈希
print(hash(Foo()))  # TypeError: unhashable type: ‘Foo‘

類名相當於變量名

class Foo:
    def chi(self,food):
        print(吃魚和,food)
class Bar:
    def chi(self,food):
        print(吃肉和,food)
dic = {Foo:面包,Bar:牛奶}
for k,v in dic.items():
    k().chi(v)
結果
吃魚和 面包
吃肉和 牛奶

self:誰調用的就是誰,類型是根據調用方的對象來進行變換的
super:表示的是父類

特殊成員:
__init__() # 創建對象的時候初始化操作
__call__() # 對象()
__getitem__() # 對象[哈哈]
__setitem__() # 對象[哈哈] = 值
__new__() # 創建對象的時候.開辟內存
__hash__() # 可哈希 hash()

__call__ 
對象後面加括號,觸發執行
註:構造方法的執行是由創建對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()
class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print(__call__)

obj = Foo()  # 執行 __init__
obj()  # 執行 __call__
結果
__call__

事例2
class Foo:
    def __init__(self):                 # 初始化操作
        print(我是init,我是第二)

    def __new__(cls, *args, **kwargs):  # 創建,是真正的構造方法,可以開辟內存
        print(我是new,我是第一)
        return object.__new__(cls)

    def __call__(self, *args, **kwargs): # 對象()   
        print(我是對象call)

    def __getitem__(self, item):        # 對象[]
        print(item,item)
        print(我是getite)

    def __setitem__(self, key, value):  # 對象[key] = value
        print(key,key)
        print(value,value)
Foo()
f = Foo()          # 自動執行__init__()
f()                # 調用__call__()
print(callable(f)) # 對象()
print(f[娃哈哈]) #自動調用__getitem__()
f[]=劉麗     #自動的調用__getitem__()
結果
我是new,我是第一
我是init,我是第二
我是new,我是第一
我是init,我是第二
我是對象call
True
item 娃哈哈
我是getite
None
key 人
value 劉麗


事例3
class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print(del obj[key]時,我執行)
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print(del obj.key時,我執行)
        self.__dict__.pop(item)

f1=Foo(sb)
f1[age]=18
f1[age1]=19
print(f1.__dict__)
del f1.age1
del f1[age]
f1[name]=alex
print(f1.__dict__)
結果
{name: sb, age: 18, age1: 19}
del obj.key時,我執行
del obj[key]時,我執行
{name: alex}


事例4
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    #這個對象字符串的表示
    def __str__(self):  #返回該對象的字符串表示形式
        return f{self.name},{self.age}
    def __repr__(self):  #該對象的官方的字符串表示形式
        return f{self.name},{self.age}
s = Person(bob,18)
print(s)
結果
bob,18

事例5
class B:
    def __str__(self):
        return str : class B
    def __repr__(self):
        return repr : class B
b = B()
print(%s % b)     #這個執行的是__str__函數方法
print(%r % b)     #這個執行的是__repr__函數方法
結果
str : class B 
repr : class B


__del__
析構方法,當對象在內存中被釋放時,自動觸發執行
註:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。
class Foo:

    def __del__(self):
        print(執行我啦)

f1=Foo()
del f1
print(------->)
結果
執行我啦
------->

python類與類之間的關系