阿里云Python入门(下)笔记、摘录。
函数
函数参数
3. 可变参数
>>> def hello(*arg):
for i in arg:
print(i)
>>> hello(1,2,3)
1
2
3
加了星号(*)的变量名会存放所有未命名的变量参数,该变量类型为元组。
4. 关键词参数
>>> def func(**arg):
for i in arg:
print(f'{i} : {arg[i]}.')
>>> func(a=1,b=2)
a : 1.
b : 2.
关键字参数允许传入零个到任意个参数,它们在函数内部自动组装为一个字典 (dict),注意传入时候的输入格式是 a=1
而不是字典初始化时的 a:1
。
闭包
如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包,通过闭包可以访问外层非全局作用域的变量,这个作用域称为闭包作用域。
>>> def funcX(x):
def funcY(y):
return x + y
return funcY
>>> a = funcX(1)
>>> a(2)
3
注意假如要在外部使用内嵌函数,一定 return
相应的值。
如果要修改闭包作用域中的变量则需要 nonlocal
关键字
>>> def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
>>> outer()
100
100
类与对象
继承
# 类定义
class people:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
grade = ''
def __init__(self, n, a, w, g):
# 调用父类的构函
people.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
s = student('小马的程序人生', 10, 60, 3)
s.speak()
# 小马的程序人生 说: 我 10 岁了,我在读 3 年级
注意继承的时候需要调用父类的构造函数来初始化父类相关变量,也可以使用super函数super().__init__()
。
魔法方法
这部分之前完全没有概念,所以把几个比较常见的摘录下来,然后之后真的用到再看
魔法方法总是被双下划线包围,例如__init__
。
魔法方法的第一个参数应为cls
(类方法) 或者self
(实例方法)。
cls
:代表一个类的名称self
:代表一个实例对象的名称
基本的魔法方法
-
__init__(self[, ...])
构造器,当一个实例被创建的时候调用的初始化方法。 -
__new__(cls[, ...])
在一个对象实例化的时候所调用的第一个方法,在调用__init__
初始化前,先调用__new__
。__new__
至少要有一个参数cls
,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
。__new__
对当前类进行了实例化,并将实例返回,传给__init__
的self
。但是,执行了__new__
,并不一定会进入__init__
,只有__new__
返回了,当前类cls
的实例,当前类的__init__
才会进入。
-
__del__(self)
析构器,当一个对象将要被系统回收之时调用的方法。 -
__str__(self)
:- 当你打印一个对象的时候,触发__str__
- 当你使用%s格式化的时候,触发__str__
- str强转数据类型的时候,触发__str__
-
__repr__(self)
:repr是str的备胎- 有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
- repr(obj)内置函数对应的结果是__repr__的返回值
- 当你使用%r格式化的时候 触发__repr__
迭代器
把一个类作为一个迭代器使用需要在类中实现两个魔法方法__iter__()
与 __next__()
。
__iter__(self)
定义当迭代容器中的元素的行为,返回一个特殊的迭代器对象, 这个迭代器对象实现了__next__()
方法并通过StopIteration
异常标识迭代的完成。__next__()
返回下一个迭代器对象。StopIteration
异常用于标识迭代的完成,防止出现无限循环的情况,在__next__()
方法中我们可以设置在完成指定循环次数后触发StopIteration
异常来结束迭代。
class Fibs:
def __init__(self, n=10):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > self.n:
raise StopIteration
return self.a
fibs = Fibs(100)
for each in fibs:
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89
生成器
在 Python 中,使用了 yield
的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
def libs(n):
a = 0
b = 1
while True:
a, b = b, a + b
if a > n:
return
yield a
for each in libs(100):
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89