这篇是对20224.12课程的学习报告及自我思考。涉及动态语言和生成器、迭代器、闭包、装饰器。
下面是第一部分,关于动态语言。
class Person(object):
def __init__(self, name):
self.name = name
p1 = Person("老王")
p1.sex = "男"
print(p1.name, p1.sex)
# 老王 男
从这段代码所展示的内容中,我们可以看出,当没有类属性时,可以通过【实例对象名.类名】为某个类的实例对象添加属性并调用。
class Person(object):
def __init__(self, name):
self.name = name
p1 = Person("老王")
p1.sex = "男"
print(p1.name, p1.sex)
Person.sex = "女"
p2 = Person("王夫人")
# 虽然没有给实例对象添加属性,但是类定义sex属性,当实例属性找不到的时候会在类属性中查找
print(p2.sex)
print(p1.name, p1.sex)
# 老王 男
# 女
# 老王 男
这段代码和上端代码有点类似,不过这里是对类添加属性,当实例找不到属性时将会在类属性中寻找,即此代码中“王夫人”的“性别”直接用了类属性“女”,而”老王“拥有自己的实例属性“男”。
def run(self, speed):
print("{}跑,速度{}".format(self.name, speed))
"""p2.run = run()
p2.run()"""
import types
p2.run = types.MethodType(run, p2)
p2.run(1)
# 王夫人跑,速度1
在上述代码后再加入这段代码。这段代码的作用时前两段代码的进阶版,它的作用是对实例对象添加类方法,不过这份类方法只能被这个实例对象所调用,即在没有对p1进行p2同样的操作前,只有p2可以通过Person类调用run方法。
class Person(object):
__slots__ = ("sex", "age")
p = Person()
p.sex = "男"
p.age = 18
# p.name = "1"
这段代码介绍的是__slots__的功能,除了之前说过在类之外为实例添加属性,也可以用这条内置函数阻止后续代码为此类的实例添加方法,目的是为了提高代码的安全性。
------------------------------------------------------------------------------------------------------------------------------------------
生成器
list1 = (x for x in range(10))
print(list1)
print(next(list1))
print(next(list1))
print(next(list1))
# <generator object <genexpr> at 0x0120A4C0>
# 0
# 1
# 2
生成器只会将生成数据的方式储存起来,每次使用执行一次
yield的用法
def createNum():
print("---1---")
a,b = 0,1
for i in range(5):
print("---2---")
yield b
print("---3---")
a,b = b,a+b
num = createNum()
print(num)
print(next(num))
# ---1---
# ---2---
# 1
def createNum():
print("---1---")
a,b = 0,1
for i in range(5):
print("---2---")
yield b
print("---3---")
a,b = b,a+b
num = createNum()
print(num)
print(next(num))
print(num.__next__())
# ---1---
# ---2---
# 1
# ---3---
# ---2---
# 1
这两段代码可以体现yield的作用 ,即将生成器由此断开,并且在下次使用时从这里开始。
def createNum():
a,b = 0,1
for i in range(5):
tempfile = yield b
print(tempfile)
a,b = b,a+b
c = createNum()
# next(c)
c.__next__()
# send 是给一个整体(yield)传递值
c.send("a")
这段代码,首先告诉我们,关于yield是什么,答案是yield不存储任何值,即使输出也是NONE。而send可以为yield传递值。并且程序遇到yield就会停止,再加上等式先执行右边再执行左边,如果没有执行过一次next,即使用了send也会应为无值可赋而报错。
多任务处理
def test1():
while True:
print("---1---")
yield None
def test2():
while True:
print("---2---")
yield None
# 协程处理 只定义了生成器(储存了数据生成的方式,等待调用)
t1 = test1()
t2 = test2()
while True:
t1.__next__()
t2.__next__()
迭代器
from collections import Iterable
print(isinstance("abc",Iterable))
print(isinstance(123,Iterable))
用于判断是否可以迭代
str1 = "abc"
#转化成迭代器
a = iter(str1)
print(next(a))
print(next(a))
print(next(a))
"""
for i in a:
print(i)
"""
用于转换迭代器
*闭包*
def test1(number):
print("---1---")
def test_in():
print("---2---")
print(number+100)
print("---3---")
return test_in
a = test1(100)
print(a)
a()
# ---1---
# ---3---
# <function test1.<locals>.test_in at 0x00C24658>
# ---2---
# 200
这段代码中a指向的斌不是text1,而是text_in
装饰器
def w1(func):
def inner():
print("权限认证中")
func()
return inner
@w1
def f1():
print("f1")
@w1
def f2():
print("f2")
f1()
f2()