18 面向对象进阶

##getattribute isinstance issubclass

class Foo():
    def __init__(self,x):
        self.x = x
    def __getattr__(self, item):
        print('执行的是getattr')#当下一个方法抛出异常 接着避免程序崩溃
    def __getattribute__(self, item):
        print('执行的是getattribute')
        raise AttributeError('抛出异常了') #抛出异常找小弟去了
    class Bar(Foo):
        pass
f1 = Foo(10)
print(isinstance(f1,Foo)) #判断此实例是否来自此类
print(issubclass(Bar,Foo)) #判断是否为子类
print(f1.xx)
View Code


#item是基于字典的方式对数据进行操作

class Foo:
    def __getitem__(self, item):
        print('getitem')
        return self.__dict__.keys()
    def __setitem__(self, key, value):
        print('setitem')
        self.__dict__[key] = value
    def __delitem__(self, key):
        print('delitem')
        self.__dict__.pop(key)
f1 = Foo()
print(f1.__dict__)
f1['name'] = 'egg'
f1[1] = '22'
print(f1.__dict__)
# del f1.name
del f1['name']
print(f1.__dict__)

##str & repr
二者皆用于控制输出 但不能输出非字符串类型

class Foo:
    def __init__(self,name,age):
        self.name =name
        self.age = age
    def __str__(self):
        print('name is %s age is %s'%(self.name,self.age))
        return 'str自定制的对象显示方式' #打印实例时的显示
    def __repr__(self): #在解释器中作用
        return 'name is %s age is %s' %(self.name,self.age)
        pass
f1 = Foo('alex',18)
print(f1) #若找不到str 就找repr做替代品
View Code

自定制format

 class Date:
     def __init__(self,year,mon,day):
         self.year = year
         self.mon = mon
         self.day = day
d1 = Date(2019,3,1)
print(d1.__dict__)
x = '{0.year}-{0.mon}-{0.day}'.format(d1)
print(x)

format_dict = {
                        'ymd':'{0.year}{0.mon}{0.day}',
                        'y-m-d':'{0.year}-{0.mon}-{0.day}'
                        }
class Date:
    def __init__(self,year,mon,day):
        self.year = year
        self.mon = mon
        self.day = day
    def __format__(self, format_spec):
        print('format is running')
        if not format_spec or format_spec not in format_dict:
            format_spec = 'ymd'
            fm = format_dict[format_spec]
            return fm.format(self)
d1 = Date(2019,3,1)
print(format(d1))   

slota__是什么 是一个类变量 变量值可以是列表 元组 也可以是可迭代对象
引子:使用点来访问属性本质就是在访问类或者对象的dict属性字典
(类的字典是共享的 而每个实例是独立的)

class Foo:
     __slots__ = 'name'
f1 = Foo()
f1.name = 'egg'
print(f1.name)

# doc
class Foo:
    'i am distribute'
     pass
class Bar(Foo):
    pass
    print(Bar.__doc__) #属性无法继承子类
    print(Foo.__doc__)

#from lib.aa import C
# c1 = C()
# print(c1.name)
# print(c1.module) #查询来自哪个模块
# print(c1.class) #查询来自哪个类

#析构方法

class Foo:
    def __init__(self,name):
        self.name = name
    def __del__(self):
print('i am running')
f1 = Foo('alex')
del f1
del f1.name
print('__________>>>')

# # __call__
# #对象后面加括号 触发执行

class Foo:
    def __call__(self, *args, **kwargs):
         print('实例能执行啦 obj()')
         pass
f1 = Foo()
f1()

#迭代器协议

class Foo:
    def __init__(self,n):
         self.n = n
    def __iter__(self):
         return self
    def __next__(self):
         if self.n == 13:
         raise StopIteration('stop!!!!')
         self.n+=1
         return self.n
# f1 = Foo(10)
# # print(f1.__next__())
# # print(f1.__next__())
# # print(f1.__next__())
# # print(f1.__next__())
# for i in f1:
#     print(i)

#斐波那契数列

import time
class Fib:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def __iter__(self):
        return self
    def __next__(self):
        if self.a > 100 or self.b > 100:
        raise StopIteration('stop!!!!')
        self.a,self.b = self.b,self.a + self.b
        return self.a
# f1 = Fib(1,1)
# print(f1.__next__())
# print(f1.__next__())
# for i in f1:
# time.sleep(0.2)
# print(i)

# 优先级:类属性 数据描述符 实例属性 非数据描述符
# 找不到的属性触发__getattr__()

引用模块时注意路径:

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

猜你喜欢

转载自www.cnblogs.com/louzhiyuan/p/10458168.html