python学习(十七)——补充内置函数、使用迭代器协议实现斐波那契数列、描述符、pycharm的问题

一、补充内置函数

#--------------------------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()

猜你喜欢

转载自blog.csdn.net/qq_28334183/article/details/83541488