内建属性 _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   #原来函数的说明文档
posted @ 2018-06-22 14:16  rianley  阅读(130)  评论(0编辑  收藏  举报