python學習(十七)——補充內建函式、使用迭代器協議實現斐波那契數列、描述符、pycharm的問題
阿新 • • 發佈:2018-11-30
一、補充內建函式
#--------------------------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()