坚持就是胜利,今天继续学习!
首先谈到了内建属性,那么什么是内建属性呢?其实就是在创建python对象时,这个对象本身带有的属性。
例如:__init__,__new__,__del__,等都属于内建属性。
接下来谈一谈内建属性当中的__getattribute__属性,当我们访问对象的任意属性的时候这个属性会自动调用
class Test:
def __init__(self,value):
self.subject1 = value
self.subject2 = "cpp"
def __getattribute__(self, item):
if item == "subject1":
print("Print Log...")
return "value:" + item
else:
return super(Test, self).__getattribute__(item)
t = Test("subject1")
print(t.subject1)
print(t.subject2)
运行结果:
Print Log...
value:subject1
cpp
我们看这样的一个例子,在__getattribute__的参数item是一个字符串,指的是访问属性的名字。上面用if语句判断我们访问的属性名是不是“subject1”。而else下面的super()函数是一个内建函数,我们可以利用他来从父类当中调用__getattribute__()方法,当然,我们还可以写成
return object.__getattribute__(self,item)
其中object指的是Test的父类。
接着我们看下一个例子,在这里我们対上面的代码进行了一些修改
class Test:
def __init__(self,value):
self.subject1 = value
self.subject2 = "cpp"
def __getattribute__(self, item):
if item == "subject1":
print("我是subject1...")
return "value:" + item
else:
print("我不是subject1...")
temp = super(Test, self).__getattribute__(item)
print("====>"+str(temp))
return temp
def show(self):
pass
t = Test("subject1")
print(t.subject1)
print(t.subject2)
t.show()
运行结果:
我是subject1...
value:subject1
我不是subject1...
====>cpp
cpp
我不是subject1...
====><bound method Test.show of <__main__.Test object at 0x0000029F85734390>>
这次我们新加入了一个函数,发现在调用函数的时候也会放访问到__getattribute__,我们用一个temp变量接收一下它的返回值看看是怎么回事,返回了一个字符串,原来Test.show就是这个函数的引用,我们也可以把它当做是一个属性,它指向了show()函数。
这个和在外部给类添加方法的原理是一样的
import types
class Test:
def __init__(self,value):
self.subject1 = value
self.subject2 = "cpp"
def __getattribute__(self, item):
if item == "subject1":
print("我是subject1...")
return "value:" + item
else:
print("我不是subject1...")
temp = super(Test, self).__getattribute__(item)
print("====>"+str(temp))
return temp
def show(self):
print("I'm show...")
Test.show = types.MethodType(show,Test)
t = Test()
t.eat()
在这里产生了一个疑问,要调用父类的方法呢?
其实原因是如果我们直接调用__getattribute__(),如果在__getattribute__当中访问到了当前类的属性,那么就会进入死循环,无限的去调用__getattribute__()。
接下来看几个python的内建函数
def double(x):
return x * 2
the_list = map(double,[1,2,3,4,5])
print(the_list)
for i in the_list:
print(i)
map()函数返回了一个迭代器(python3.x),在python2.x当中返回的是列表
运行结果:
<map object at 0x0000020F2E4242B0>
2
4
6
8
10
同样我们可以用匿名函数来实现这样的一个功能
the_list = map(lambda x : x*2,[1,2,3,4,5])
print(the_list)
for i in the_list:
print(i)
运行结果同上。
接下来认识一下filter()函数,
the_iter = filter(lambda x : x % 2,[1,2,3,4,5])
print(the_iter)
for i in the_iter:
print(i)
运行结果:
<filter object at 0x0000023668A94EB8>
1
3
5
上面的例子中,filter()函数会返回当x%2为True时的一个迭代器,x代表后面列表中的每个数。
接下来复习了一下集合的知识
A = "guasdoafjoasjd"
B = "ijfijajdjdjdoa"
a = set(A) # 将A转化为集合
b = set(B) # 将B转化为集合
print(a)
print(b)
print(a&b) #取a和b的交集
print(a|b) # 取a和b的并集
print(a^b) # 取a和b的对称差集
运行结果:
{'s', 'f', 'j', 'g', 'u', 'o', 'a', 'd'}
{'f', 'j', 'i', 'o', 'a', 'd'}
{'f', 'j', 'o', 'a', 'd'}
{'s', 'f', 'j', 'i', 'g', 'u', 'o', 'a', 'd'}
{'s', 'i', 'g', 'u'}
接下来简单的认识了一下functools模块
import functools as f
# reduce函数在python3.x之后被加入到functools模块当中,看看结果想一下它实现了什么功能?
the_int = f.reduce(lambda x,y:x+y,[1,2,3,4,5])
print(the_int)
def test(*args,**kwargs):
print(args)
print(kwargs)
p1 = f.partial(test,1,2,3)
p1() #在函数调用的时候,上面的1,2,3三个参数默认传递进去了
p1(4,5,6)
p1(hello="baby")
def decorate(func):
"I'm in decorate"
@f.wraps(func) # 这里如果不加上,下面的help会展示出什么样的信息?
def ornament():
"I'm in ornament"
print("装饰器被调用...")
return func()
return ornament
@decorate
def test2():
"I'm in test2"
print("Hello world")
print(help(test2))
运行结果:
15
(1, 2, 3)
{}
(1, 2, 3, 4, 5, 6)
{}
(1, 2, 3)
{'hello': 'baby'}
Help on function test2 in module __main__:
test2()
I'm in test2
None
从结果能看出上面三个函数分别实现了什么功能?
第一个reduce()函数实现了一个迭代的过程1赋给x,2赋给y,而后x+y再赋给x,3赋给y...以此类推。
第二个partial()函数实现了保存了一些默认参数的功能,
第三个wraps()函数是针对于help说明的时候使用,如果不使用wraps打印的是装饰器里面的说明而不是test2()中的。