day28面向對象進階

===============================自省===============================
    hasattr(obj,'屬性')->>有屬性是否存在
    getattr(obj,'屬性')->>獲取屬性是否存在,不存在報錯
    delattr(obj,'屬性','默認值')->>獲取obj.屬性  不存在不會報錯,返回那個默認的值
    setattr(obj,'屬性','屬性的值')obj.屬性=屬性的值
    delattr(obj,'屬性')->>del obj.屬性
        __getattr__:obj[屬性]的方式去操作屬性時候時觸發的方法
        __setattr__:
        __delattr__:

        __getitem__:obj[屬性] 時候觸發
        __setitem__:obj[屬性] =屬性的值 觸發
        __delitem__:obj[]

    描述符就是一個新式類,這個類至少實現以下殺個方法的一個
        __get__,
        __set__,
        __delete__,
        class Foo():
            def __get__():
                pass
            def __set__():
                pass
            def __delete__():
                pass
        class Bar():
            name='oulen'
        obj=Foo()
        obj.name='oulen'
    ==============__str__fan方法
    class Foo1(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self)
            return "bar(%s %s)"%(self.name,self.age)
    b=Foo1('oulen',128) 
    print(b)       
================call方法
    class Foo():
        pass
        def __call__(self, *args, **kwargs):
            print('我執行啦obj()')

    f1=Foo()
    f1()#調用的就是__call__方法
============doc屬性===========
    class Foo():
        '我是描述信息'
        pass
    class Bar():
        pass
    print(Foo.__dict__)
    print(Bar.__dict__)
=================文件描述符號================
    #f=open('a.txt')
    #文件操作
    # with open('a.txt','w') as f:
    #     f.writelines('你好')
    #     print(f.readline(1))

    class Foo():
        def __init__(self,name):
            self.name=name
        def __enter__(self):
            print('執行enter')
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('執行exit')
            print(exc_tb)
            print(exc_type)
            print(exc_val)
            return True
    with Foo('a.txt') as f:
        pass
        print(f)
        print(f.name)
        print('aiga')
        # print('->>>>>>>')
        # print('->>>>>>>')
        # print('->>>>>>>')
        # print('->>>>>>>')
    print('00000000000')

    #with obj as f:
        #'代碼塊'
    # with obj ->>觸發obj.__enter__()方法,拿到返回值,
    #  as f--f=返回值

    #with obj as f= f=obj.__enter__()
    #執行代碼快
    #一:沒有異常的情況下,代碼塊運行完畢以後觸發__exit__()運行,三個參數爲None
    #二:有異常的情況下,從異常的位置觸發__exit__()
        #a:如果__exit__的返回值是True代表吞掉異常
        #b:如果__exit__的返回值是不爲True,代表吐出了異常
        #c:__exit__的運行完畢就代表整個with運行完畢
    #with open()#好處是能夠執行自動清理

=====================================元類=============================
    # class Foo():
    #     pass
    #
    # f1=Foo()
    # print(type(f1))
    # print(type(Foo))
    # print(type(type))
    #
    # class Bar():
    #     pass

    #元類就是模板
    #元內是用來創建模板的,正如類是創建對象的模板
    #type 是python內置的元類

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

    print(Foo)
    FFo=type('FFo',(object,),{'x':1,'__init__':__init__})
    print(FFo)
    f1=FFo('oulen',18)
    print(FFo.__dict__)

    #兩種定義


=====================================利用描述符號自定義元類==================
    class Lazypropetry():
        def __init__(self,func):
            print('==============',func)
            self.func=func
        def __get__(self, instance, owner):
            print('get_')
            print(instance)
            print(owner)
            if instance is None:
                return self
            res=self.func(instance)
            setattr(instance,self.func.__name__,res)
            return res

    class Room():
        x=Lazypropetry('x')
        def __init__(self,name,width,length):
            self.name=name
            self.width=width
            self.length=length

        @Lazypropetry #
        def area2(self):
            return self.width * self.length
        @property #
        def area1(self):
            return self.width * self.length
        @property
        def test(self):
            return '1111111'
    # r1=Room('廁所',1,1)
    # print(r1.area)
    # print(Room.__dict__)
    r1=Room('cesuo',1,1)
    print(r1.area)
    #類調用
    #實例調用



    #類屬性
    #數據描述符
    #實例屬性
    #非數據描述符號
    #找不到

    print(r1.area)

=============================描述符的應用==========================
    class Typed:
        def __init__(self,key,expected_type):
            self.key=key
            self.expected_type=expected_type
        def __get__(self, instance, owner):
            print('get方法')
            # print('instance參數【%s】' %instance)
            # print('owner參數【%s】' %owner)
            return instance.__dict__[self.key]
        def __set__(self, instance, value):
            print('set方法')
            # print('instance參數【%s】' % instance)
            # print('value參數【%s】' % value)
            # print('====>',self)
            if not isinstance(value,self.expected_type):
                # print('你傳入的類型不是字符串,錯誤')
                # return
                raise TypeError('%s 傳入的類型不是%s' %(self.key,self.expected_type))
            instance.__dict__[self.key]=value
        def __delete__(self, instance):
            print('delete方法')
            # print('instance參數【%s】' % instance)
            instance.__dict__.pop(self.key)
    class People:
        name=Typed('name',str) #t1.__set__()  self.__set__()
        age=Typed('age',int) #t1.__set__()  self.__set__()
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary

    # p1=People('alex','13',13.3)
    p1=People(213,13,13.3)

    # p1=People('alex',13,13.3)
    # print(p1.__dict__)
    # p1=People(213,13,13.3)
    # print(p1.__dict__)
    # print(p1.__dict__)
    # print(p1.name)

    # print(p1.__dict__)
    # p1.name='egon'
    # print(p1.__dict__)


    # print(p1.__dict__)
    # del p1.name
    # print(p1.__dict__)

    # print(p1)

    # print(p1.name)
    # p1.name='egon'
    # print(p1.name)
    # print(p1.__dict__)

===================================類的裝飾器=======================
    # def deco(func):
    #     print("------------")
    #     return func
    #
    # @deco
    # def test():
    #     print('test函數運行')
    #
    # test()
    # def deco(obj):
    #     print('----------',obj)
    #     return obj
    #
    # @deco
    # class Foo():
    #     print('nihao')
    # print(Foo.__dict__)

    def test():
        print('函數')
    test.x=1
    test.y=2
    print(test.x)
===========================類的裝飾器的應用====================
    class Typed:
        def __init__(self,key,expected_type):
            self.key=key
            self.expected_type=expected_type
        def __get__(self, instance, owner):
            print('get方法')
            # print('instance參數【%s】' %instance)
            # print('owner參數【%s】' %owner)
            return instance.__dict__[self.key]
        def __set__(self, instance, value):
            print('set方法')
            # print('instance參數【%s】' % instance)
            # print('value參數【%s】' % value)
            # print('====>',self)
            if not isinstance(value,self.expected_type):
                # print('你傳入的類型不是字符串,錯誤')
                # return
                raise TypeError('%s 傳入的類型不是%s' %(self.key,self.expected_type))
            instance.__dict__[self.key]=value
        def __delete__(self, instance):
            print('delete方法')
            # print('instance參數【%s】' % instance)
            instance.__dict__.pop(self.key)
    def deco(**kwargs):
        def wrapper(obj):
            for key,val in kwargs.items():
                print('---',key,val)
                Typed(key,val)
                setattr(obj,key,val)
                setattr(obj,key,Typed(key,val))
                
            return obj
    class People:
        name=Typed('name',str) #t1.__set__()  self.__set__()
        age=Typed('age',int) #t1.__set__()  self.__set__()
        def __init__(self,name,age,salary,gender,height):
            self.name=name
            self.age=age
            self.salary=salary

    # p1=People('alex','13',13.3)
    # p1=People(213,13,13.3)

    print(People.__dict__)
    # p1=People('alex',13,13.3)
    # print(p1.__dict__)
    # p1=People(213,13,13.3)
    # print(p1.__dict__)
    # print(p1.__dict__)
    # print(p1.name)

    # print(p1.__dict__)
    # p1.name='egon'
    # print(p1.__dict__)


    # print(p1.__dict__)
    # del p1.name
    # print(p1.__dict__)

    # print(p1)

    # print(p1.name)
    # p1.name='egon'
    # print(p1.name)
    # print(p1.__dict__)

=================類的裝飾器的修訂版==========================
    def Type(**kwargs):
        def deco(obj):
            for key ,val in kwargs.items():
                setattr(obj,key,val)
                return obj
        print('+++',kwargs)
        return deco
    @Type(x=1,y=2,z=3) #Foo=deco(Foo)   #1.Type(x=1,y=2,z=3) ->>deco, 2@deco=------Foo=deco(Foo)

    class Foo():
        print('ooo')
==================自定製元類======================
    class MyType(type):
        def __init__(self,a,b,c):
            print('自定製元類')
            print(a)
            print(b)
            print(c)
        def __call__(self, *args, **kwargs):
            print('============')
            print(self)
            print(args,kwargs)
            obj=object.__new__(self)
            self.__init__(obj,**args,**kwargs)
            return obj
    class Foo(metaclass=MyType):#MyType(Foo,'Foo',,(object))
        def __init__(self,name):
            self.name=name

    f1=Foo('alex')
    print(f1)
    print(f1.__dict__)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章