一、补充内置函数
#--------------------------isinstance/isinbclass--------------
class Foo:
pass
class Bar(Foo):
pass
b1=Bar()
print(isinstance(b1,Bar)) # b1是否是Bar类
print(isinbclass(Bar,Foo)) # Bar是否继承Foo
print(type(b1))
#------------------------__getattr__/__getattribute__-----------------
class Foo:
def __init__(self,x):
self.x=x
def __getattr__(self, item):
print('执行的是getattr')
return self.__dict__[item]
def __getattribute__(self, item): # 一定触发
print('执行的是getattribute')
raise AttributeError('抛出异常了') # 抛出异常,触发__getattr__
# raise TabError('xxxxxx')
f1=Foo(10)
# f1.x
f1.xxxxxx # 不存在的属性访问,触发__getattr__
#---------------------item系列方法-------------------------------------
# 适用字典
class Foo:
def __getitem__(self, item):
print('getitem',item)
return self.__dict__[item]
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='egon' #---->setattr-------->f1.__dict__['name']='egon'
f1['name']='egon'#--->setitem--------->f1.__dict__['name']='egon'
f1['age']=18
print('===>',f1.__dict__)
# del f1.name
# print(f1.__dict__)
#
# print(f1.age)
del f1['name']
print(f1.__dict__)
print(f1['age'])
raise S
#-----------------------------str------------------------------------
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '名字是%s 年龄是%s' %(self.name,self.age)
f1=Foo('egon',18)
print(f1) # str(f1)--->f1.__str__()
#-------------------__repr__------------------------
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age
# def __str__(self):
# return '折是str'
def __repr__(self):
return '名字是%s 年龄是%s' %(self.name,self.age)
f1=Foo('egon',19)
#repr(f1)---->f1.__repr__()
print(f1) # str(f1)---》f1.__str__()------>f1.__repr__()
#--------------------------自定制format---------------------
format_dic={
'ymd':'{0.year}{0.mon}{0.day}',
'm-d-y':'{0.mon}-{0.day}-{0.year}',
'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('我执行啦')
print('--->',format_spec)
if not format_spec or format_spec not in format_dic:
format_spec='ymd'
fm=format_dic[format_spec]
return fm.format(self)
d1=Date(2016,12,26)
# format(d1) #d1.__format__()
# print(format(d1))
print(format(d1,'ymd'))
print(format(d1,'y:m:d'))
print(format(d1,'m-d-y'))
print(format(d1,'m-d:y'))
print('===========>',format(d1,'asdfasdfsadfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd'))
#-------------------------------slots------------------------------
'''
字典会占用大量内存,如果有一个属性很少的类,但是有很多实例,为了节省空间可以使用该方法
'''
class Foo:
__slots__=['name','age'] #{'name':None,'age':None}
# __slots__='name' #{'name':None,'age':None}
f1=Foo()
# f1.name='egon'
# print(f1.name)
# f1.age=18 #--->setattr----->f1.__dict__['age']=18
# print(f1.__dict__)
print(Foo.__slots__)
print(f1.__slots__)
f1.name='egon'
f1.age=17
print(f1.name)
print(f1.age)
# f1.gender='male'
f2=Foo()
print(f2.__slots__)
f2.name='alex'
f2.age=18
print(f2.name)
print(f2.age)
#-----------------------__doc__---------------------------
'''
查看文档信息
'''
class Foo:
'我是描述信息'
pass
class Bar(Foo):
pass
# print(Bar.__doc__) #该属性无法继承给子类
# print(Bar.__doc__) #该属性无法继承给子类
#------------------------__module__/__class__--------------
from lib.aa import C
c1=C()
print(c1.name)
print(c1.__module__)
print(c1.__class__)
#----------------------__del__-----------------------------
# 一般无需定义,析构方法-当对象在内存中被释放时,自动触发执行
class Foo:
def __init__(self,name):
self.name=name
def __del__(self):
print('我执行啦')
f1=Foo('alex')
# del f1 #删除实例会触发__del__
del f1.name #删除实例的属性不会触发__del__
print('--------------------->')
# 程序运行完毕会自动回收内存,触发__del__
#--------------------------------__call__----------------
'''
对象后面加括号执行
'''
class Foo:
def __call__(self, *args, **kwargs):
print('实例执行啦 obj()')
f1=Foo()
f1() #f1的类Foo 下的__call__
Foo() #Foo的类 xxx下的__call__
#-----------------------------__next__和__iter__实现迭代器协议--------
# 实现迭代
class Foo:
def __init__(self,n):
self.n=n
def __iter__(self):
return self
def __next__(self):
if self.n == 13:
raise StopIteration('终止了')
self.n+=1
return self.n
for i in f1: # obj=iter(f1)------------>f1.__iter__()
print(i) #obj.__next_()
二、使用迭代器协议实现斐波那契数列
class Fib:
def __init__(self):
self._a=1
self._b=1
def __iter__(self):
return self
def __next__(self):
if self._a > 100:
raise StopIteration('终止了')
self._a,self._b=self._b,self._a + self._b
return self._a
f1=Fib()
print(next(f1))
print(next(f1))
print(next(f1))
print(next(f1))
print(next(f1))
print('==================================')
for i in f1:
print(i)
三、描述符
1、描述符
class Foo:
def __get__(self, instance, owner):
print('===>get方法')
def __set__(self, instance, value):
print('===>set方法',instance,value)
instance.__dict__['x']=value #b1.__dict__
def __delete__(self, instance):
print('===>delete方法')
class Bar:
x=Foo() #在何地?
def __init__(self,n):
self.x=n #b1.x=10
b1=Bar(10)
print(b1.__dict__)
b1.x=11111111111111111
print(b1.__dict__)
b1.y=11111111111111111111111111111111111111
print(b1.__dict__)
2、注意事项
'''
1、描述符本身应该定义成新式类,被代理的类也应该是新式类
2、必须把描述符定义成这个类的类属性,不能定义到析构函数中
3、要严格遵循优先级,如下
类属性 > 数据描述符 > 实例属性 > 非数据描述符 > 找不到的属性__getattr__
'''
四、软件开发规范
'''
program
|--bin
|--conf
|--db
|--lib
|--log
|--src
'''
五、pycharm的问题
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
from bin import start # bin/start.py
'''
寻找路径:
# 当前目录
# sys.path 环境变量
pycharm自动把当前项目添加到环境变量中
'''
index.say_hi()