上课讲代码真不如布置几道题自己写写。

# 组合数据类型

每种组合数据类型都是一个类。组合数据类型包括:

  • 序列类型
  • 集合类型
  • 映射类型

# 函数参数

# 位置参数和关键字参数

# 使用元组传参

可变参数只能在参数列表的最后,通过参数前加 * 实现,内部类型为元组 (tuple) 类型。下面是一个简单的例子。

dev vfunc (a, *b):
    print(type(b))
    for n in b:
        a += b
    return a

# 使用字典传参

使用字典传参不需要再定义时指定参数个数和名称,通过 ** 实现。其收集所有未匹配的关键字参数,因此不会与 * 重复。

def g(**kwargs):
    print(type(kwargs))
    print(kwargs)
g()
g(PKU="北京大学", RUC="中国人民大学", THU="清华大学")

在 Python 中, kwargs 是一个约定俗成的表示,意思是 keyword arguments 即关键字参数。

也可以直接传入 **<dict> , 就相当于将字典中的每个 pair 作为关键字参数传入函数。

my_dict = {"name":"zhangsan", "age":32}
temp(**my_dict)

如果精通这两个接口,大概就可以写一些很容易兼容的框架。

# 闭包

闭包就是能读取其他函数内部变量的函数,有点类似与 Java 反射。形成需要满足如下要求:

  1. 必须有一个内嵌函数。
  2. 内嵌函数必须引用外部函数中的变量。
  3. 外部函数的返回值必须是内嵌函数。
def func_out():
    num1 = 10
    def func_in(num2):
        res = num1 + num2
        print("res= ", res)
    return func_in
new_func = func_out()
new_func(20)

# 装饰器

装饰器实质上是一个闭包函数,其参数有且仅有一个并且是函数类型,其功能是为其它函数增加额外的功能。使用装饰器的原因是 Python 的开闭原则,即对扩展开放,对修改封闭。下面是一个例子:

def work():
    for i in ragne(10000):
        print(i)

那么如何在不改变上述函数源代码和调用方式的前提下为其增加统计调用时间的功能?

def decorator(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print("time: ", end - start)
    return inner
@decorator # 等价于 work = decorator (work)
def work():
    for i in range(10000):
        print(i)

装饰器也可以带参数。

# 类装饰器

# 内存

# 对象的回收

# 可变对象和不可变对象

# VGG Net