1. 程式人生 > >python3 類的相關內容

python3 類的相關內容

自己的 open 找到 方法名 setname 產生 創建對象 foo ssm

轉自:https://blog.csdn.net/rozol/article/details/69317339

相當的詳細

定義類

技術分享圖片
#coding=utf-8
# class_my.py 定義類 (新式類)

# 定義類
class Person:
    # 類屬性 (class) (註:類/類方法 能修改類屬性; 對象不能修改類屬性,更改的只是實例屬性)
    name = "name" # 公共屬性
    __adress = "adress" # 私有屬性 (__屬性 表示私有)

    # 構造方法(對象創建調用) (__init__ 表示構造)
    def __init__(self, name, address = "
地球"): # 實例屬性 self.name = name # (註:類屬性與實例屬性名稱相同時用實例屬性,實例屬性被刪除後使用類屬性) self.__adress = address Person.setData(self) # 析構方法(對象銷毀調用) (__del__ 表示析構) def __del__(self): print("對象被銷毀.") # toString() def __str__(self): return "Person.class" #
實例方法 (this) def setName(self, name): # self可為其他字符串 (this) self.name = name; # 修改 實例屬性 (不存在自動添加) # 類方法 (static) @classmethod def setName_cls(cls, name): cls.name = name # 修改 類屬性 # 靜態方法 (tools) @staticmethod def setName_sta(name): # (註:參數部分) return
name def getName(self): return self.name def setData(self): # 實例屬性 self.__age = 21 # 私有屬性 self.sex = "" # 公共屬性 def show(self): print("Hello! %s"%self.name) print("Address:%s"%self.__adress) # 使用自身私有屬性 self.__eat() # 使用自身私有方法 def __eat(self): # 私有方法 print("eat") # ======= 函數調用 ====== if __name__ == "__main__": # - 創建對象 - ps = Person("LY") # --- 調用方法 --- # 調用實例方法 ps.setName("LY") # 實例調用 實例方法 ps.show() # 調用類方法 Person.setName_cls("Person") # 類調用 類方法 ps.setName_cls("Person") # 實例調用 類方法 # 調用靜態方法 () print(ps.setName_sta("Per")) # 實例調用 靜態方法 print(Person.setName_sta("Per")) # 類調用 靜態方法 # --- 訪問屬性 --- print(ps.getName()) print(ps.name) # 訪問 類屬性 的公共屬性值 print(ps.sex) # 訪問 實例屬性 的公共屬性值 # --- 修改屬性 --- # 修改實例屬性 ps.name = "123" # 修改 類屬性 (註:並非真修改,只是向對象中創建了一個實例屬性) del ps.name # 刪除 實例屬性 (註:實例不能(非類方法)刪除 類屬性, 只是刪除了對象中創建的實例屬性,類屬性依然存在) del ps.sex # 刪除 實例屬性 (註:真刪除,刪除後不能訪問) # 修改類屬性 Person.name = "Person" # 修改類屬性 Person.setName_cls("Person") # 類 調用 類方法 修改 類屬性 (註:類不能調用實例方法) ps.setName_cls("Person") # 對象 通過 類方法 修改 類屬性 del Person.name # 刪除類屬性 # - 刪除對象 - del ps # > Less is more! "靜態方法"和"類方法/屬性"同級都可理解為"靜態",靜態方法適合做工具箱,類方法/屬性可認為在靜態區,隨手拿來即用,而實例則需要實例化才能使用. (--本人的個人理解) # ======= 函數調用 ======
View Code

繼承

技術分享圖片
#coding=utf-8
# class_extend.py 繼承(新式類)

# --- 單繼承 ---
# 父類
class Animal(object):

    def __init__(self, name = "動物"):
        self.name = name

    def run(self):
        print("%s在跑."%self.name)

# 子類
class Cat(Animal): # 繼承 (父類寫()內)

    def __init__(self, name, ot = ""):
        super(Cat, self).__init__(name)

    def miao(self):
        print("")



# --- 多繼承 ---
class Donkey: #
    def walk(self):
        print("walk")

    def eat(self):
        print("Donkey.eat")

class Horse: #
    def run(self):
        print("run")

    def eat(self):
        print("Horse.eat")

class Mule(Donkey, Horse): # 騾(驢+馬)
    pass



# === 多態 ====
def animalRun(animal): # 參數接收自己及其自己的子類
    animal.run()




# ======= 函數調用 ======
if __name__ == "__main__":
    # - 單繼承調用 -
    ani = Animal()
    ani.run()

    cat = Cat("")
    cat.run()
    cat.miao()


    # - 多繼承調用 -
    mule = Mule()
    mule.walk()
    mule.run()
    mule.eat() # 多個父類中有相同的方法時,調用()內最前面的父類(Donkey)的方法


    # - 多態調用 -
    ani = Animal()
    animalRun(ani)

    cat = Cat("")
    animalRun(cat)
# ======= 函數調用 ======
View Code

重寫

技術分享圖片
#coding=utf-8
# class_rewrite.py 重寫(新式類)

class Animal(object):

    def run(self):
        print("Animal.run")

    def eat(self, food = "食物"):
        print("eat:%s"%food)


class Cat(Animal):

    # 子類重寫了父類的方法
    def run(self):
        print("Cat.run")

    def eat(self):
        # 調用父類的方法
        super(Cat, self).eat("貓糧")



# ======= 函數調用 ======
if __name__ == "__main__":
    ani = Animal()
    ani.run()
    ani.eat()
    cat = Cat()
    cat.run()
    cat.eat()
# ======= 函數調用 ======
View Code

屬性方法

技術分享圖片
#!/usr/bin/env python
# coding=utf-8
__author__ = Luzhuo
__date__ = 2017/5/13
# class_propertiemethod.py 屬性方法
# 屬性方法: 把方法變成靜態屬性


# 寫法1
class PM_1(object):
    def __init__(self):
        self.__name_str = "PropertieMethod_1"

    # 獲取
    @property
    def name(self):  # 註意,方法名相同
        return self.__name_str

    # 設置
    @name.setter
    def name(self, name):
        self.__name_str = name

    # 刪除
    @name.deleter
    def name(self):
        del self.__name_str


if __name__ == "__main__":
    pm = PM_1()
    print(pm.name)
    pm.name = "PM"
    print(pm.name)
    del pm.name
    # print(pm.name)

# ==========================================================


# 寫法2
class PM_2(object):
    def __init__(self):
        self.__name_str = "PropertieMethod_2"

    # 獲取
    def getname(self):
        return self.__name_str

    # 設置
    def setname(self, name):
        self.__name_str = name

    # 刪除
    def delname(self):
        del self.__name_str

    # property(fget=None, fset=None, fdel=None, doc=None) # 返回一個property 屬性, 實現原理見 內置函數 文章 property_my 塊代碼(http://blog.csdn.net/rozol/article/details/70603230)
    name = property(getname, setname, delname)


if __name__ == "__main__":
    p = PM_2()
    print(p.name)
    p.name = "PM2"
    print(p.name)
    del p.name
    # print(p.name)
View Code

反射

技術分享圖片
#!/usr/bin/env python
# coding=utf-8
__author__ = Luzhuo
__date__ = 2017/5/13
# class_reflection.py 反射
# 通過反射機制,可動態修改程序運行時的狀態/屬性/方法
# Python的反射機制性能如何? 在Android中Java的反射產生垃圾而執行gc,從而導致UI不流暢,而且性能低
# Python的反射性能(1億次測試): 直接獲取屬性值:反射獲取屬性值 = 1:1.164 ;直接設置屬性值:反射設置屬性值 = 1:1.754

def setname(self, name):
    self.name = name

class Clazz(object):
    def __init__(self):
        self.name = "Clazz"

    def getname(self):
        return self.name



if __name__ == "__main__":
    c = Clazz()

    # --- 方法 ---
    if hasattr(c, "getname"):
        # 獲取
        method = getattr(c, "getname", None)
        if method:
            print("setname_ref: {}".format(method()))  # 獲取方法對象並執行

    if not hasattr(c, "setname"):
        # 添加
        setattr(c, "setname", setname)  # 添加方法
        method = getattr(c, "setname", None)
        if method:
            method(c, "Reflection")
        print("setname_raw: {}".format(c.getname()))

    if hasattr(c, "setname"):
        # 刪除
        delattr(c, "setname")
        # c.setname(c, "Demo")


    # --- 屬性 ---
    if not hasattr(c, "age"):
        # 添加
        setattr(c, "age", 21)  # 添加方法
        var = getattr(c, "age", None)
        print("age_ref: {}".format(var))
        print("age_raw: {}".format(c.age))

    if hasattr(c, "age"):
        # 獲取
        var = getattr(c, "age", None)
        print("age_ref: {}".format(var))

    if hasattr(c, "age"):
        # 刪除
        delattr(c, "age")
        # print("age_raw: {}".format(c.age))
View Code

文檔註釋

技術分享圖片
#!/usr/bin/env python
# coding=utf-8
__author__ = Luzhuo
__date__ = 2017/5/13
# class_doc.py 文檔註釋
# 文檔註釋的編寫

class Foo(object):
    ‘‘‘
    這是一個類
    ‘‘‘

    def method(self, data):
        ‘‘‘
        這是一個方法
        :param data: 需要的數據
        :return: 返回的數據
        ‘‘‘
        return "method"


def func(data):
    ‘‘‘
    這是一個函數
    :param data: 需要的數據
    :return: 返回的數據
    ‘‘‘
    return "func"



if __name__ == "__main__":
    # 打印文檔
    print(Foo.__doc__)
    print(Foo().method.__doc__)

    print(func.__doc__)
View Code

創建類的原理

技術分享圖片
#!/usr/bin/env python
# coding=utf-8
__author__ = Luzhuo
__date__ = 2017/5/13
# class_origin.py 類的由來
# 類由type類實例化產生, 而type由解釋器產生

age = 21

def __init__(self):
    self.name = "origin"

def getname(self):
    return self.name

def setname(self, name):
    self.name = name

def delname(self):
    del self.name


if __name__ == "__main__":
    # 用type創建類(類名, 基類元組, 類成員字典)
    Foo = type(Foo, (object,), {__init__ : __init__, "getname" : getname, "setname" : setname,
                                  "delname": delname, "age" : age})
    # 實例化類
    f = Foo()
    # 使用
    print(f.age)
    print(f.getname())
    f.setname("ClassOrigin")
    print(f.getname())
    f.delname()
    # print(f.getname())

# ==================================================================================





# 元類 (type創建類原理)
# 元類是用於創建所有類的類, Python中是type類 (註意,類也是對象,也是被創建出來的,即萬物皆對象), 下面將演示type類的功能

# __call__ 的調用 (__new__在__init__之前調用, __call__在什麽時候調用呢)
class Foobar(object):
    def __call__(self, *args, **kwargs):
        print("Foobar __call__")

if __name__ == "__main__":
    fb = Foobar()
    fb()  # 只有在這個時候才會調用__call__屬性

    Foobar()()  # 等同於該方式

# ------


# metaclass指定類有誰來創建
# Python創建類時會尋找__metaclass__屬性,(包括父類)沒有找到將使用內建元類type
class MyType(type):
    def __init__(self, *args, **kwargs):
        print("MyType __init__")

    def __call__(self, *args, **kwargs):
        print("MyType __call__")
        obj = self.__new__(self)
        self.__init__(obj, *args, **kwargs)
        return obj

    def __new__(cls, *args, **kwargs):
        print("MyType __new__")
        return type.__new__(cls, *args, **kwargs)


class Foo(object, metaclass=MyType):  # (Python3.x寫法) metaclass 用於創建類, Python創建類時會尋找__metaclass__屬性,(包括父類)沒有找到將使用內建元類type

    # __metaclass__ = MyType # Python2.x寫法

    def __init__(self):
        print("Foo __init__")

    def __new__(cls, *args, **kwargs):  # 用於實例化對象
        print("Foo __new__")
        return object.__new__(cls)  # 必須是返回

    def show(self):
        print("Foo show")


if __name__ == "__main__":
    print("start")
    f = Foo()
    f.show()
    # MyType __new__ => MyType __init__ => ‘start‘ => MyType __call__ => Foo __new__ => Foo __init__ => ‘Foo show‘
View Code

其他的一些補充

技術分享圖片
#!/usr/bin/env python
# coding=utf-8
__author__ = Luzhuo
__date__ = 2017/5/13
# class_other.py 關於類的一些補充


class Demo(object):
    def show(self):
        print("Demo show")

if __name__ == "__main__":
    # __module__ 該對象的模塊名
    # __class__ 該對象的類對象
    print(Demo.__module__)  # 該對象的模塊名 => __main__
    print(Demo.__class__)  # 該對象的類對象 => <class ‘type‘>

    obj = Demo()
    print(obj.__module__)  # 該對象的模塊名 => __main__
    print(obj.__class__)  # 該對象的類對象 => <class ‘__main__.Demo‘>
    obj.__class__.show(obj)  # 類對象可被使用

    # ============================

    # __dict__ 類或對象中的所有成員
    print(Demo.__dict__)  # 類屬性
    print(obj.__dict__)  # 實例屬性
View Code

python3 類的相關內容