简介
函数
1. 函数的定义
2. 函数的调用
3. 函数文档
4. 函数参数
5. 函数的返回值
6. 变量作用域
Lambda-表达式
1. 匿名函数的定义
2. 匿名函数的应用
类与对象
1. 属性和方法组成对象
2. self是什么?
3. Python的魔法方法
4. 公有和私有
5. 继承
6. 组合
7. 类、类对象和实例对象
8. 什么是绑定?
9. 一些相关的内置函数(BIF)
魔法方法
1. 基本的魔法方法
2. 算术运算符
3. 反算术运算符
4. 增量赋值运算
5. 一元运算符
6. 属性访问
7. 描述符
8. 定制序列
9. 迭代器
Python 是一种通用编程语言,其在科学计算和机器学习领域具有广泛的应用。如果我们打算利用 Python 来执行机器学习,那么对 Python 有一些基本的了解就是至关重要的。本 Python 入门系列体验就是为这样的初学者精心准备的。
本实验包括以下内容:
还记得 Python 里面“万物皆对象”么?Python 把函数也当成对象,可以从另一个函数中返回出来而去构建高阶函数,比如: 参数是函数、返回值是函数。
我们首先来介绍函数的定义。
def
关键词开头,后接函数名和圆括号()。None
。def functionname (parameters):
"函数文档字符串"
functionsuite
return [expression]
【例子】
1
def printme(str):
2
print(str)
3
4
5
printme("我要调用用户自定义函数!") # 我要调用用户自定义函数!
6
printme("再次调用同一函数") # 再次调用同一函数
7
temp = printme('hello') # hello
8
print(temp) # None
我要调用用户自定义函数! 再次调用同一函数 hello None
1
def MyFirstFunction(name):
2
"函数定义过程中name是形参"
3
# 因为Ta只是一个形式,表示占据一个参数位置
4
print('传递进来的{0}叫做实参,因为Ta是具体的参数值!'.format(name))
5
6
7
MyFirstFunction('老马的程序人生')
8
# 传递进来的老马的程序人生叫做实参,因为Ta是具体的参数值!
9
10
print(MyFirstFunction.__doc__)
11
# 函数定义过程中name是形参
12
13
help(MyFirstFunction)
14
# Help on function MyFirstFunction in module __main__:
15
# MyFirstFunction(name)
16
# 函数定义过程中name是形参
传递进来的老马的程序人生叫做实参,因为Ta是具体的参数值! 函数定义过程中name是形参 Help on function MyFirstFunction in module __main__: MyFirstFunction(name) 函数定义过程中name是形参
Python 的函数具有非常灵活多样的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。从简到繁的参数形态如下:
1. 位置参数
def functionname(arg1):
"函数文档字符串"
functionsuite
return [expression]
arg1
- 位置参数 ,这些参数在调用函数 (call function) 时位置要固定。2. 默认参数
def functionname(arg1, arg2=v):
"函数文档字符串"
functionsuite
return [expression]
arg2 = v
- 默认参数 = 默认值,调用函数时,默认参数的值如果没有传入,则被认为是默认值。【例子】
1
def printinfo(name, age=8):
2
print('Name:{0},Age:{1}'.format(name, age))
3
4
5
printinfo('小马') # Name:小马,Age:8
6
printinfo('小马', 10) # Name:小马,Age:10
Name:小马,Age:8 Name:小马,Age:10
【例子】
1
def printinfo(name, age):
2
print('Name:{0},Age:{1}'.format(name, age))
3
4
5
printinfo(age=8, name='小马') # Name:小马,Age:8
Name:小马,Age:8
3. 可变参数
顾名思义,可变参数就是传入的参数个数是可变的,可以是 0, 1, 2 到任意个,是不定长的参数。
def functionname(arg1, arg2=v, *args):
"函数文档字符串"
functionsuite
return [expression]
*args
- 可变参数,可以是从零个到任意个,自动组装成元组。【例子】
1
def printinfo(arg1, *args):
2
print(arg1)
3
for var in args:
4
print(var)
5
6
7
printinfo(10) # 10
8
printinfo(70, 60, 50)
9
# 70
10
# 60
11
# 50
10 70 60 50
4. 关键字参数
def functionname(arg1, arg2=v, args, *kw):
"函数文档字符串"
functionsuite
return [expression]
**kw
- 关键字参数,可以是从零个到任意个,自动组装成字典。【例子】
1
def printinfo(arg1, *args, **kwargs):
2
print(arg1)
3
print(args)
4
print(kwargs)
5
6
7
printinfo(70, 60, 50)
8
# 70
9
# (60, 50)
10
# {}
11
printinfo(70, 60, 50, a=1, b=2)
12
# 70
13
# (60, 50)
14
# {'a': 1, 'b': 2}
70 (60, 50) {} 70 (60, 50) {'a': 1, 'b': 2}
「可变参数」和「关键字参数」的同异总结如下:
5. 命名关键字参数
def functionname(arg1, arg2=v, args, *, nkw, *kw):
"函数文档字符串"
functionsuite
return [expression]
*, nkw
- 命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw 前面加个分隔符 *
。【例子】
1
def printinfo(arg1, *, nkw, **kwargs):
2
print(arg1)
3
print(nkw)
4
print(kwargs)
5
6
7
printinfo(70, nkw=10, a=1, b=2)
8
# 70
9
# 10
10
# {'a': 1, 'b': 2}
11
12
printinfo(70, 10, a=1, b=2)
13
# TypeError: printinfo() takes 1 positional argument but 2 were given
70 10 {'a': 1, 'b': 2}
nwk
,因此 10 被当成「位置参数」,而原函数只有 1 个位置函数,现在调用了 2 个,因此程序会报错。6. 参数组合
在 Python 中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这 5 种参数中的 4 个都可以一起使用,但是注意,参数定义的顺序必须是:
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args
接收的是一个 tuple
**kw
是关键字参数,kw
接收的是一个 dict
命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名关键字参数不要忘了写分隔符 *
,否则定义的是位置参数。
警告:虽然可以组合多达 5 种参数,但不要同时使用太多的组合,否则函数很难懂。
【例子】
1
def add(a, b):
2
return a + b
3
4
5
print(add(1, 2)) # 3
6
print(add([1, 2, 3], [4, 5, 6])) # [1, 2, 3, 4, 5, 6]
3 [1, 2, 3, 4, 5, 6]
【例子】
1
def back():
2
return [1, '小马的程序人生', 3.14]
3
4
5
print(back()) # [1, '小马的程序人生', 3.14]
[1, '小马的程序人生', 3.14]
【例子】
1
def back():
2
return 1, '小马的程序人生', 3.14
3
4
5
print(back()) # (1, '小马的程序人生', 3.14)
(1, '小马的程序人生', 3.14)
【例子】
1
def printme(str):
2
print(str)
3
4
temp = printme('hello') # hello
5
print(temp) # None
6
print(type(temp)) # <class 'NoneType'>
hello None <class 'NoneType'>
【例子】
1
def discounts(price, rate):
2
final_price = price * rate
3
return final_price
4
5
6
old_price = float(input('请输入原价:')) # 98
7
rate = float(input('请输入折扣率:')) # 0.9
8
new_price = discounts(old_price, rate)
9
print('打折后价格是:%.2f' % new_price) # 88.20
请输入原价:98 请输入折扣率:0.9 打折后价格是:88.20
global
和nonlocal
关键字了。【例子】
1
num = 1
2
3
4
def fun1():
5
global num # 需要使用 global 关键字声明
6
print(num) # 1
7
num = 123
8
print(num) # 123
9
10
11
fun1()
12
print(num) # 123
1 123 123
内嵌函数
【例子】
1
def outer():
2
print('outer函数在这被调用')
3
4
def inner():
5
print('inner函数在这被调用')
6
7
inner() # 该函数只能在outer函数内部被调用
8
9
10
outer()
11
# outer函数在这被调用
12
# inner函数在这被调用
outer函数在这被调用 inner函数在这被调用
闭包
【例子】
1
def funX(x):
2
def funY(y):
3
return x * y
4
5
return funY
6
7
8
i = funX(8)
9
print(type(i)) # <class 'function'>
10
print(i(5)) # 40
<class 'function'> 40
【例子】闭包的返回值通常是函数。
1
def make_counter(init):
2
counter = [init]
3
4
def inc(): counter[0] += 1
5
6
def dec(): counter[0] -= 1
7
8
def get(): return counter[0]
9
10
def reset(): counter[0] = init
11
12
return inc, dec, get, reset
13
14
15
inc, dec, get, reset = make_counter(0)
16
inc()
17
inc()
18
inc()
19
print(get()) # 3
20
dec()
21
print(get()) # 2
22
reset()
23
print(get()) # 0
3 2 0
【例子】 如果要修改闭包作用域中的变量则需要 nonlocal
关键字
1
def outer():
2
num = 10
3
4
def inner():
5
nonlocal num # nonlocal关键字声明
6
num = 100
7
print(num)
8
9
inner()
10
print(num)
11
12
13
outer()
14
15
# 100
16
# 100
100 100
递归
【例子】n! = 1 x 2 x 3 x ... x n
1
# 利用循环
2
n = 5
3
for k in range(1, 5):
4
n = n * k
5
print(n) # 120
6
7
# 利用递归
8
def factorial(n):
9
if n == 1:
10
return 1
11
return n * factorial(n - 1)
12
13
14
print(factorial(5)) # 120
120 120
【例子】斐波那契数列 f(n)=f(n-1)+f(n-2), f(0)=0 f(1)=1
1
# 利用循环
2
i = 0
3
j = 1
4
lst = list([i, j])
5
for k in range(2, 11):
6
k = i + j
7
lst.append(k)
8
i = j
9
j = k
10
print(lst)
11
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
12
13
# 利用递归
14
def recur_fibo(n):
15
if n <= 1:
16
return n
17
return recur_fibo(n - 1) + recur_fibo(n - 2)
18
19
20
lst = list()
21
for k in range(11):
22
lst.append(recur_fibo(k))
23
print(lst)
24
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
【例子】设置递归的层数,Python默认递归层数为 100
1
import sys
2
3
sys.setrecursionlimit(1000)
在 Python 里有两类函数:
def
关键词定义的正规函数lambda
关键词定义的匿名函数Python 使用 lambda
关键词来创建匿名函数,而非def
关键词,它没有函数名,其语法结构如下:
lambda argument_list: expression
lambda
- 定义匿名函数的关键词。argument_list
- 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。:
- 冒号,在函数参数和表达式中间要加个冒号。expression
- 只是一个表达式,输入函数参数,输出一些值。注意:
expression
中没有 return 语句,因为 lambda 不需要它来返回,表达式本身结果就是返回值。【例子】
1
def sqr(x):
2
return x ** 2
3
4
5
print(sqr)
6
# <function sqr at 0x000000BABD3A4400>
7
8
y = [sqr(x) for x in range(10)]
9
print(y)
10
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
11
12
lbd_sqr = lambda x: x ** 2
13
print(lbd_sqr)
14
# <function <lambda> at 0x000000BABB6AC1E0>
15
16
y = [lbd_sqr(x) for x in range(10)]
17
print(y)
18
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
19
20
21
sumary = lambda arg1, arg2: arg1 + arg2
22
print(sumary(10, 20)) # 30
23
24
func = lambda *args: sum(args)
25
print(func(1, 2, 3, 4, 5)) # 15
<function sqr at 0x00000220081D9E18> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <function <lambda> at 0x00000220081FF400> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 30 15
函数式编程 是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。
【例子】非函数式编程
1
def f(x):
2
for i in range(0, len(x)):
3
x[i] += 10
4
return x
5
6
7
x = [1, 2, 3]
8
f(x)
9
print(x)
10
# [11, 12, 13]
[11, 12, 13]
【例子】函数式编程
1
def f(x):
2
y = []
3
for item in x:
4
y.append(item + 10)
5
return y
6
7
8
x = [1, 2, 3]
9
f(x)
10
print(x)
11
# [1, 2, 3]
[1, 2, 3]
匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中,主要有两种形式:
如,在 filter
和map
函数中的应用:
filter(function, iterable)
过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list()
来转换。【例子】
1
odd = lambda x: x % 2 == 1
2
templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
3
print(list(templist)) # [1, 3, 5, 7, 9]
[1, 3, 5, 7, 9]
map(function, *iterables)
根据提供的函数对指定序列做映射。【例子】
1
m1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
2
print(list(m1))
3
# [1, 4, 9, 16, 25]
4
5
m2 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
6
print(list(m2))
7
# [3, 7, 11, 15, 19]
[1, 4, 9, 16, 25] [3, 7, 11, 15, 19]
除了 Python 这些内置函数,我们也可以自己定义高阶函数。
【例子】
1
def apply_to_list(fun, some_list):
2
return fun(some_list)
3
4
lst = [1, 2, 3, 4, 5]
5
print(apply_to_list(sum, lst))
6
# 15
7
8
print(apply_to_list(len, lst))
9
# 5
10
11
print(apply_to_list(lambda x: sum(x) / len(x), lst))
12
# 3.0
15 5 3.0
对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。
我们可以使用关键字 class
定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。