【python学习笔记】第4天

坚持就是胜利,今天继续学习!

首先谈到了内建属性,那么什么是内建属性呢?其实就是在创建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()中的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值