13 内建属性 _getattribute_ 内建函数
1.内建属性
2.__getattribute__ 属性访问时拦截器
class Itcast(object): def __init__(self,subject1): self.subject1 = subject1 self.subject2 = 'cpp' #属性访问时拦截器,打log def __getattribute__(self,obj): #obj----> subject if obj == 'subject1': print('log subject1') return 'redirect python' else: #测试时注释掉这2行,将找不到subject2 return object.__getattribute__(self,obj) def show(self): print('this is Itcast') s = Itcast("python") print(s.subject1) print(s.subject2)
运行结果:
log subject1
redirect python
cpp
带方法的
class Itcast(object): def __init__(self,subject1): self.subject1 = subject1 self.subject2 = "cpp" #属性访问时拦截器,打log def __getattribute__(self,obj): print("====1>%s"%obj) if obj == "subject1": print("log subject1") return "redirect python" else: temp = object.__getattribute__(self,obj) print("===2>%s"%str(temp)) return temp def show(self): print("thi si Itcast") s = Itcast("python") print(s.subject1) print(s.subject2) s.show()
====1>subject1 log subject1 redirect python ====1>subject2 ===2>cpp cpp ====1>show ===2><bound method Itcast.show of <__main__.Itcast object at 0x7efe2d627898>> thi si Itcast
3 __getattribute__的坑
class Person(object): def __getattribute__(self,obj): print("---test---") if obj.startswith("a"): return "hahha" else: return self.test #return object.__getattribute__(self,obj) #扔给父类给你处理 def test(self): print("heihei") t.Person() t.a #返回hahha t.b #会让程序死掉 #原因是:当t.b执行时,会调用Person类中定义的__getattribute__方法,但是在这个方法的执行过程中 #if条件不满足,所以 程序执行else里面的代码,即return self.test 问题就在这,因为return 需要把 #self.test的值返回,那么首先要获取self.test的值,因为self此时就是t这个对象,所以self.test就是 #t.test 此时要获取t这个对象的test属性,那么就会跳转到__getattribute__方法去执行,即此时产 #生了递归调用,由于这个递归过程中 没有判断什么时候推出,所以这个程序会永无休止的运行下去,又因为 #每次调用函数,就需要保存一些数据,那么随着调用的次数越来越多,最终内存吃光,所以程序 崩溃 # # 注意:以后不要在__getattribute__方法中调用self.xxxx
4。内建函数
1) range
### python2 直接生成[0-100] In [1]: range(0,10) Out[1]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2)map函数
map函数会根据提供的函数对指定序列做映射
#函数需要一个参数 map(lambda x: x*x, [1, 2, 3]) #结果为:[1, 4, 9]
l1 = [ 0, 1, 2, 3, 4, 5, 6 ] l2 = [ 'Sun', 'M', 'T', 'W', 'T', 'F', 'S' ] l3 = map( f1, l1, l2 ) print(list(l3)) #结果为:[(0, 'Sun'), (1, 'M'), (2, 'T'), (3, 'W'), (4, 'T'), (5, 'F'), (6, 'S')]
3)filter函数
filter函数会对指定序列执行过滤操作
filter(lambda x: x%2, [1, 2, 3, 4]) [1, 3] filter(None, "she") 'she'
4)reduce函数
reduce函数,reduce函数会对参数序列中元素进行累积
reduce(lambda x, y: x+y, [1,2,3,4]) 10 reduce(lambda x, y: x+y, [1,2,3,4], 5) 15 reduce(lambda x, y: x+y, ['aa', 'bb', 'cc'], 'dd') 'ddaabbcc'
5)sorted函数
5. 集合set
集合与之前列表、元组类似,可以存储多个数据,但是这些数据是不重复的
集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric_difference(对称差集)等数学运算.
>>> x = set('abcd') >>> x {'c', 'a', 'b', 'd'} >>> type(x) <class 'set'>
>>> y = set(['h','e','l','l','o']) >>> y {'h', 'e', 'o', 'l'}
>>> z = set('spam') >>> z {'s', 'a', 'm', 'p'}
>>> y&z #交集 set() >>> >>> >>> x&z #交集 {'a'} >>> >>> >>> x|y #并集 {'a', 'e', 'd', 'l', 'c', 'h', 'o', 'b'} >>> >>> x-y #差集 {'c', 'a', 'b', 'd'} >>> >>> >>> x^z #对称差集(在x或z中,但不会同时出现在二者中) {'m', 'd', 's', 'c', 'b', 'p'} >>> >>> >>> len(x) 4 >>> len(y) 4 >>> len(z) 4 >>>
6. functools
In [23]: import functools In [24]: dir(functools) Out[24]: ['WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'cmp_to_key', 'partial', 'reduce', 'total_ordering', 'update_wrapper', 'wraps']
1)partial函数(偏函数)
把一个函数的某些参数设置默认值,返回一个新的函数,调用这个新函数会更简单。
import functools def showarg(*args, **kw): print(args) print(kw) p1=functools.partial(showarg, 1,2,3) p1() p1(4,5,6) p1(a='python', b='itcast') p2=functools.partial(showarg, a=3,b='linux') p2() p2(1,2) p2(a='python', b='itcast')
2)wraps函数
使用装饰器时,有一些细节需要被注意。例如,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)。
添加后由于函数名和函数的doc发生了改变,对测试结果有一些影响,例如:
def note(func): "note function" def wrapper(): "wrapper function" print('note something') return func() return wrapper @note def test(): "test function" print('I am test') test() print(test.__doc__)
运行结果
note something
I am test
wrapper function
所以,Python的functools包中提供了一个叫wraps的装饰器来消除这样的副作用。例如:
import functools def note(func): "note function" @functools.wraps(func) def wrapper(): "wrapper function" print('note something') return func() return wrapper @note def test(): "test function" print('I am test') test() print(test.__doc__)
运行结果 note something I am test test function #原来函数的说明文档