Python-面向對象之高級進階

classmethod與staticmethod

裝飾器,都可以裝飾類內部的方法函數

classmethod :使該方法綁定給類來使用,稱爲類的綁定方法ui

staticmethod:使該方法變成了一個普通函數,即非綁定方法code

再來複習一下對象的綁定方法特殊之處對象

對象的綁定方法特殊之處:ip

​ - 由對象調用,會將對象當作第一個參數傳入該方法內存

類的綁定方法特殊之處:md5

​ - 由類來調用,會將類名當作第一個參數傳入該方法utf-8

上代碼字符串

import settings
import uuid
import hashlib


class People:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    # 將該方法裝飾成類的綁定方法
    # 登陸認證,從配置文件中讀取用戶名密碼
    @classmethod
    def login_auth(cls):
        obj = cls(settings.USER,settings.PWD)
        return obj

    # 將該方法裝飾成一個普通的函數,不會自動傳值,對象or類均可以調用
    @staticmethod
    def create_id():
        uuid_obj = uuid.uuid4()
        return hashlib.md5(str(uuid_obj).encode("utf-8")).hexdigest()

    
    def index(self):
        print("驗證經過,顯示主頁")


# 用classmethod 裝飾過的方法返回一個對象
obj = People.login_auth()       # 在該方法中經過讀取配置文件的參數實例化出一個對象
obj.index()     # 將返回出去的對象調用其餘方法

# 調用 staticmethod 裝飾過的方法,即普通函數,由類調用,也能夠對象調用
print(People.create_id())

面向對象高級

isinstance、issubclass

python中內置的函數,均傳入兩個參數(參數1,參數2)

isinstance:判斷一個對象是不是一個類的實例(判斷一個對象是不是已知類型)

issubclass:判斷一個類是不是另外一個類的子類。

class Foo:
    pass

class Bar(Foo):
    pass

# isinstance    判斷對象是不是類的實例
f = Foo()
print(isinstance(f,Foo))        # True
l = [1,2]
print(isinstance(l,list))       # True


# issubclass    判斷類是不是另外一個類的子類
print(issubclass(Bar,Foo))      # True

反射

反射☞的是經過 「字符串」 對 對象或類的屬性進行操做

hasattr:經過字符串,判斷該字符串是不是對象或類的屬性

getattr:經過字符串,獲取對象或類的屬性

setattr:經過字符串,設置對象或類的屬性

delattr:經過字符串,刪除對象或類的屬性

上代碼

class People:
    country = "China"
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

# hasattr   傳兩個參數,判斷對象有沒有屬性
p1 = People("qinyj",18,"nan")
print(hasattr(p1,"country"))        # True

# getattr   傳三個參數,也能夠傳兩個參數,若是屬性不存在報錯
p2 = People("qinyj",18,"nan")
print(getattr(p2,"country","China"))

# setattr   傳兩個參數,設置對象的屬性
p3 = People("qinyj",18,"nan")
setattr(p3,"country","China")
print(getattr(p3,"country",))

# delattr   傳兩個參數,刪除對象的屬性
p4 = People("qinyj",18,"nan")
# delattr(p4,"country")
# print(getattr(p4,"country",))
# 反射練習
class Movie:
    def input_cmd(self):
        print("請輸入命令")
        while True:
            cmd = input("請輸入執行的方法名").strip()
            
            # hasattr 與 getattr 連用實例
            if hasattr(self,cmd):
                getattr(self,cmd)()
                
    def upload(self):
        print("電影開始上傳")

    def download(self):
        print("電影開始下載")
m = Movie()
m.input_cmd()

魔法方法(類內置方法)

凡是在類內部定義,"__名字__"的方法都稱之爲魔法方法,又稱類的內置方法

__init__:初始化函數,在類調用時自動觸發

__str__:打印對象的時候自動觸發

__del__:刪除對象的名稱空間,最後才執行

__getattr__:對象.屬性獲取屬性,沒有獲取到值自動觸發

__setattr__:對象.屬性賦值的時候自動觸發

__call__:在帝鄉被調用時自動觸發

__new__:在__init__前自動觸發,產生一個空的對象

class Foo(object):
    '''
    如下均是類的內置方法,
    '''

    def __new__(cls, *args, **kwargs):
        print(cls)
        return object.__new__(cls)  # 產生一個空的對象

    def __init__(self):
        print("在類調用時觸發")

    def __str__(self):
        return "在打印對象的值時觸發"

    def __del__(self):
        print("最後執行該方法,刪除內存地址")

    def __getattr__(self, item):
        return "沒有獲取對象屬性時觸發"

    def __setattr__(self, key, value):
        print("設置對象屬性值時觸發")
        print(key,value)
        self.__dict__[key] = value

    def __call__(self, *args, **kwargs):
        print("調用對象時觸發")

f = Foo()
# 打印對象
print(f)
# <class '__main__.Foo'>
# 在類調用時觸發
# 在打印對象的值時觸發
# 最後執行該方法,刪除內存地址

# 獲取對象屬性x
print(f.x)
# <class '__main__.Foo'>
# 在類調用時觸發
# 在打印對象的值時觸發
# 沒有獲取對象屬性時觸發
# 最後執行該方法,刪除內存地址


# 對象賦值新的屬性
f.x = "x"
print(f.x)
# <class '__main__.Foo'>
# 在類調用時觸發
# 在打印對象的值時觸發
# 沒有獲取對象屬性時觸發
# 設置對象屬性值時觸發
# x x
# x
# 最後執行該方法,刪除內存地址

# 對象調用
f()
# <class '__main__.Foo'>
# 在類調用時觸發
# 在打印對象的值時觸發
# 沒有獲取對象屬性時觸發
# 設置對象屬性值時觸發
# x x
# x
# 調用對象時觸發
# 最後執行該方法,刪除內存地址



class MyFile:
    def __init__(self,file_name,mode="r",encoding="utf-8"):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def file_open(self):
        self.f = open(self.file_name,self.mode,encoding=self.encoding)

    def file_read(self):
        res = self.f.read()
        print(res)

    # 使用del內置函數,在最後執行,就會調用關閉文件操做
    def __del__(self):
        self.f.close()
        print("文件關閉成功")

f = MyFile("settings.py")
f.file_open()
f.file_read()

print("程序結束,對象將被銷燬!")

單例模式

單例模式指的是單個實例,實例指的是調用類產生的對象

實例化多個對象時會產生不一樣的內存地址,單例可讓全部調用者,在調用類產生對象的狀況下都指向同一分內存地址,例如,打開文件

單例模式目的:爲了減小內存佔用

class File:
    __instance = None

    # 單例模式1
    # 使用類的綁定方法,
    @classmethod
    def singleton(cls,file_name):
        # 類中設置一個私有屬性__instance,
        # 在類本身調用完成產生一個對象,將這個對象賦值給類的這個屬性,
        # 若是這個類屬性有對象了,就說明已經實例化過了無需再次實例化,直接返回
        # 外部調用者只需調用其方法便可使用單例模式操做對象
        if not cls.__instance:
            obj = cls(file_name)
            cls.__instance = obj
        return cls.__instance

    # 單例模式2
    # 使用__new__產生一個空的對象,至關於建立一個空的對象,調用時至關於多個變量指向這個對象
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance
    '''
    實例化出來的對象內存地址同樣
    <__main__.File object at 0x000000000295C668>
    <__main__.File object at 0x000000000295C668>
    <__main__.File object at 0x000000000295C668>
    '''


    def __init__(self,file_name,mode="r",encoding="utf-8"):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name,self.mode,encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    # def __del__(self):
    #     self.f.close()

f1 = File("settings.py")
f2 = File("settings.py")
f3 = File("settings.py")
print(f1)
print(f2)
print(f3)
# 以下:產生的三個對象 內存地址均不一樣
# <__main__.File object at 0x000000000298C6D8>
# <__main__.File object at 0x000000000298C710>
# <__main__.File object at 0x000000000298C6A0>


# 讓其成爲單例模式調用
f1 = File.singleton("settings.py")
f2 = File.singleton("settings.py")
f3 = File.singleton("settings.py")
print(f1)
print(f2)
print(f3)
# 以下:產生的三個對象 內存地址均相同
# <__main__.File object at 0x0000000009F6F908>
# <__main__.File object at 0x0000000009F6F908>
# <__main__.File object at 0x0000000009F6F908>
相關文章
相關標籤/搜索