1、attr 一個效能工具,意思是,並不能提供不可取代的功能,但是卻能提高我們的編碼效率,將一些本來該造輪子操作扔給它,黑箱操作即可。
2、遇到什么問題,我們可以使用這個庫?
(1) 打印美觀
step1:打印輸出的問題用__repr__解決。
- 比如 print 打印一個對象的所有屬性,直接print obj 只能輸出這個對象的內存地址。
- print obj.__dict__打印出的是一個dict格式的屬性,但是屬性dict中的順序不是我們指定的,中文也是uft-8編碼的。
如果我想要指定屬性輸出的順序,也不想再去做解碼呢
可以這樣做,重寫魔術方法__repr__,指定輸出順序,
class test(): def person(self,name,age,sex): self.name = name self.age = age self.sex = sex def __repr__(self): return '{}(name={},age={},sex={})'.format(self.__class__.__name__,self.name,self.age,self.sex) test1 = test() test2 = test() test1.person("小明",18,"male") test2.person("小明",19,"male") print "__dict__打印:", print test1.__dict__ print "觸發__repr__打印:", print test1
對比一下可以發現__dict__是無順序打印,__repr__重構時是可以指定打印的,也不需要對漢字做解碼。
__dict__打印: {'age': 18, 'name': '\xe5\xb0\x8f\xe6\x98\x8e', 'sex': 'male'} 觸發__repr__打印: test(name=小明,age=18,sex=male)
ps.需要我們注意的是,何時觸發的__repr__(self,xxx,xxx,....)方法?
結論是,輸入對象test1,然后回車(沒試過);打印test1對象 這兩種方式都能自動觸發調用__repr__
step2:偷懶一下。如果我連__repr__函數都不想重寫呢?畢竟寫起來也是真的麻煩
這時候,就可以使用attr.s這個工具了,省去這些繁瑣的代碼編寫過程
import attr class test(): def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def __repr__(self): return '{}(name={},age={},sex={})'.format(self.__class__.__name__,self.name,self.age,self.sex) test1 = test("小明", 18, "male") print (test1) @attr.s class test_attrs(): name = attr.ib() age = attr.ib() sex = attr.ib() test2 = test_attrs("小明", 18, "male") print (test2)
打印出來是
test(name=小明,age=18,sex=male) test_attrs(name='小明', age=18, sex='male')
對比test類 用__repr__處理的打印,和test_attrs類,用的類裝飾器@attr.s 簡潔了很多,處理效果完全一樣。