[TOC]

5.数据类型转换

数据类型的转换你只需要将数据类型作为函数名即可,还有几个内置函数可以执行数据之间的转换,这些函数返回一个新的对象,表示转换的值;

数据类型转换函数列表:
int(x [,base = 10]) #将x转换为一个整数类型,或者指定一个进制类型进行转换成为整形(返回整型数据)
float(x) #函数用于将整数和字符串转换成浮点数
str(x) #将对象 x 转换为字符串

complex(real [ ,imag ]) #用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数(如果第一个参数为字符串,则不需要指定第二个参数。。)
repr(x) #将对象 x 转换为表达式字符串,为供解释器读取的形式;
tuple(s) #将序列 s 转换为一个元组
list(s) #将序列 s 转换为一个列表
set(s) #转换为可变集合
dict(d) #创建一个字典d必须是一个序列 (key,value)元组。
chr(x) #将一个整数转换为一个字符
hex(x) #将一个整数转换为一个十六进制字符串
oct(x) #将一个整数转换为一个八进制字符串
ord(x) #将一个字符转换为它的ASCII整数值
frozenset(s) #返回一个冻结的集合,冻结后集合不能再添加或删除任何元素,参数iterable-可迭代的对象,比如列表、字典、元组等等。

案例:数据类型转换函数使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python3
#coding:utf-8
#功能:数值类型转换内置函数

print("整形 : 0xa=",int('0xa',16)," 0x12=",int('12',16)," 010=",int('10',8))
#以16进制转换为整形,和8进制转换成为整形
print("浮点 :",float('123'),float(1)) #浮点类型
print("复数 :",complex(1,2),complex("1+2j")) #转化一个字符串或数为复数
#注意:这个地方在"+"号两边不能有空格,也就是不能写成"1 + 2j",应该是"1+2j",否则会报错

cdict = dict(zip(['one', 'two', 'three'], [1, 2, 3])) # 映射函数方式来构造字典

print(str(cdict)) # 将对象转化为字符串形式。
print(repr(cdict)) # 将对象转化为供解释器读取的形式。

print(eval(' 2 ** 2'),eval('pow(2,2)')) # 执行一个字符串表达式,可以执行python的一些数学函数和计算

print(set('runoob'),set('google')) # 集合中重复的值被删除 set
print(frozenset(range(10))) # 生成一个新的不可变集合 set

print(chr(48),chr(65),chr(97)) #将ASCII码 ==> 字符
print(ord('0'),ord('A'),ord('a')) #将字符 ==> ASCII
print(hex(255),hex(15))
print("255 oct =",oct(255),"10 oct =",oct(10))

Python数据类型转换函数使用

Python数据类型转换函数使用

6.操作符以及优先级

Q: 什么是运算符?
A:让变量进行加减乘除四则运算;

运算符及其优先级:

  • 算术运算符
  • 右移/左移运算符
  • 位运算符
  • 比较(关系)运算符
  • 等于运算符
  • 赋值运算符
  • 身份运算符
  • 成员运算符
  • 逻辑运算符
    Python优先级

    Python优先级

    Python优先级详细

    Python优先级详细

Python中的按位运算法:
按位运算符是把数字看作二进制来进行计算的。

& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0。
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
^ 按位异或运算符:当两对应的二进位相异时,结果为1
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。(~x 类似于 -x-1 ,在一个有符号二进制数的补码形式)。

<< 左移动运算符:运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。
>> 右移动运算符:把 “ >> “左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数 。

Python语言支持逻辑运算符:(类似玉C语言短路求值 && )

x and y 布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。
x or y 布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。
not x 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。

Python成员运算符:

包含了一系列的成员,包括字符串,列表或元组。
in 如果在指定的序列中找到值返回 True,否则返回 False。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。

Python身份运算符:

is 是判断两个标识符是不是引用自一个对象
x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is not 是判断两个标识符是不是引用自不同对象
x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。

案例:Python各种操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/python3
#coding:utf-8
#功能:特殊运算符号验证demo
#"""Python算术运算符"""
print("2 / 4 = ", 2 / 4) #除法 , 得到浮点数
print("2 // 4 = ",2 // 4) #除法 , 得到整数
print("2 ** 4 = ",2 ** 4) #乘方 ,(优先级最高)
print("5 % 4 = ",5 % 4) #取余 ,

#"""比较运算符###
a = 1
b = 2
if ( a == b ):
print ("1 - a 等于 b")
else:
print ("1 - a 不等于 b")

#"""赋值运算符###
c = a + b
c += 1
print("C值为:",c)
c **= c
print("C值为:",c)

#"""Python位运算"""
a = 1
b = 8
print("a&b = ", a&b) #与
print("a|b = ", a|b) #或
print("a^b = ", a^b) #亦或
print("~a = ", ~a) #取反
print("a<<2 = ", a<<2) #左移动

#"""Python逻辑运算符"""
a = 1
b = 2
print((a and b)) #如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。
print((a or b)) #如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。
print(not(a or b)) # 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。


#"""Python成员运算符"""
a = 10
b = 5
list = [1, 2, 3, 4, 5 ]
if(a in list):
print("a 在list列表里面")
else:
print("a 不在list列表里面")

if(b not in list):
print("a 不在list列表里面")
else:
print("b 在list列表里面")

#"""Python成员运算符"""
a = 20
b = 20
if ( a is b ):
print ("1 - a 和 b 有相同的标识")
else:
print ("1 - a 和 b 没有相同的标识")
#注: id() 函数用于获取对象内存地址
if ( id(a) == id(b) ):
print ("2 - a 和 b 有相同的标识")
else:
print ("2 - a 和 b 没有相同的标识")


a,b,c,d,e = 20,10,15,5,0
#"""算术运算符优先级验证"""
e = (a + b) * c / d #( 30 * 15 ) / 5
print ("(a + b) * c / d 运算结果为:", e)

e = ((a + b) * c) / d # (30 * 15 ) / 5
print ("((a + b) * c) / d 运算结果为:", e)

e = (a + b) * (c / d); # (30) * (15/5)
print ("(a + b) * (c / d) 运算结果为:", e)

e = a + b * c / d; # 20 + (150/5)
print ("a + (b * c) / d 运算结果为:", e)

Python各种操作符案例

Python各种操作符案例

注意事项:
1)数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。
2)在混合计算时,Python会把整型转换成为浮点数。
3)is 与 == 区别,前者用于判断两个变量引用对象是否为同一个, 后者用于判断引用变量的值是否相等。
4)逻辑运算符是 not、and 、or优先级
5)幂指数 ** 比左侧的优先级高,比右侧的优先级低
6)使用 (x>y)-(x < y) 来判断x/y是否相同,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1

7.Python流程控制语法

7.1 条件控制与循环

7.1.1 分支语句:if elif else

分支语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if 表达式:
执行语句
elif 表达式:
执行语句
else:
执行语句

#三元操作符
x if 条件 else y //如果条件为真时候将x值赋给small,为假时候将y值赋给small


#else 语句
1) else 语句跟 if 语句搭,构成“要么怎样,要么不怎样”的语境
2) else 语句跟 for / while 语句搭,构成“干完了能怎样,干不完就别想怎样”的语境
2) else 语句跟 try 语句搭构成“没有问题,那就干吧”的语境

注意事项:
1) 由于Python中无{}包含代码块,而是采用缩进的方式来判别执行的代码块;
2) 与for/while语句搭配时候,只有在循环正常执行完成后才会执行 else 语句块的内容

7.1.2循环语句:while , for..else…

退出循环关键字:break,continue,及其循环语法:

1
2
3
4
5
6
7
8
9
10
while (表达式条件):
为真则执行代码块
else:
语句为 false 时执行该 else 的语句块:


for 变量 in 表达式:
循环体
else:
它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。

案例:条件控制于循环语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/python3
#coding:utf-8
#功能:分支与循环
#-----------if 语句-----------------
guess = 8
temp = int(input("请输入一个1-10数值:"))
if guess == temp:
print("恭喜您,输入的数值刚好")
elif guess > temp:
print("太遗憾了,输入的数值小于它")
else:
print("太遗憾了,输入的数值大于它")

x,y = 1,3
print("#三元运算符 :",end="")
print( x if x > 3 else y )


#------------while 语句---------------
# Fibonacci series: 斐波纳契数列 (两个元素的总和确定了下一个数)
a,b = 0,1
while b < 10:
print(b,end=",")
a,b = b, a+b
print("\n\n")

while (1): print ('Python!')

#采用while ..else 进行素数的计算
count = 11 / 2
while count > 1:
if num % count == 0:
print("%d 最大约数是%d " %(11,count))
break #利用break跳出不执行else
count -= 1
else:
print("%d是素数" 11) #循环穷尽(为假的时候,执行遇到break不会执行)



#------------for 语句---------------
for i in "python":
print(i,end="|") #依次打印字母并以 | 分割
print()

sites = ["baidu","Google","Runoob","taobao"]
for i in sites:
print(i,end=",") #打印出列表的值
print()

for i in range(len(sites)): #或列表的长度 4 生成(0 - 3);
print(i,sites[i],len(sites[i])) #索引,列表中以索引下标的元素,元素的长度

print()
#查询是否为质数 2 - 10 那些是质数
for x in range(2,10):
for y in range(2,x):
if x % y == 0:
print(x,'等于',y , '*', x // y)
break
else:
#循环中找到元素,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。
print(x,'是质数')

Python条件控制于循环案例

Python条件控制于循环案例

7.1.3 空语句:pass

Python pass是空语句,是为了保持程序结构的完整性,pass 不做任何事情,一般用做占位语句,如下实例:

1
2
3
4
5
6
while True:
pass # 等待键盘中断 (Ctrl+C)

#最小的类:
class MyEmptyClass:
pass

8.迭代器与生成器

8.1 迭代器 iter

迭代是Python最强大的功能之一是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象;迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,且只能往前不会后退。
迭代器参数:列表/字典

迭代器有两个基本的方法:iter() 和 next()。

创建一个迭代器,使用需要在类中实现两个方法 iter() 与 next() ;并且iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成,防止出现无限循环的情况。

案例:迭代器(魔术方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/python3
# coding:utf-8
# 功能:迭代器与生成器

import sys #引入 sys 模块
list = [1, 2, 3, 4]
it = iter(list)

#** 方法1 for **#
## 其实 for 语句实现与iter迭代器差不多 ##
for x in it:
print("值", x, end=", ")
else:
print("\n---------------------------")


#***方法2 next**#
it = iter(list)
while True:
try:
print(next(it), end=",")
except StopIteration: # StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况;
sys.exit()


#**方法3 迭代器 - 魔法方法 **#
# 创建一个返回数字的迭代器,初始值为 0,逐步递增 1:运行四次
#魔法方法案例(1)
class MyNumbers:
def __iter__(self): #魔法方法
self.a = 0
return self

def __next__(self): #当
try:
if self.a <= 3:
x = self.a
self.a += 1
return x
else:
raise StopIteration
except StopIteration:
return ('迭代结束')

myclass = MyNumbers()
myiter = iter(myclass) # 实际触发了__iter__ 中 a = 0
print(next(myiter), end=" ") #运行1次 next
print(next(myiter), end=" ") #运行2次 next
print(next(myiter), end=" ") #运行3次 next
print(next(myiter), end=" ") #运行4次 next
print(next(myiter)) #第五次运行next由于条件(或抛出 StopIteration 退出迭代)

#案例二:采用魔法方法实现斐波那契数列
class Fibs:
def __init__(self):
self.a = 0
self.b = 1

def __iter__(self):
return self #返回它本身由于它自身就是迭代器

def __next__(self):
self.a, self.b = self.b,self.a + self.b
return self.a #a就是下一个斐波那契的值
# def __next__(self):
# self.a, self.b = self.b,self.a + self.b
# if self.a > 10:
# raise StopIteration #表示
# return self.a

fibs = Fibs()
for each in fibs:
if each < 20: #返回
print(each, end=" ")
else:
break


#######################
# $ python demo3.24.py
# 0 1 2 3 迭代结束
# 1 1 2 3 5 8 13

Python迭代器案例

Python迭代器案例

8.2 生成器 yield

使用yield的函数被称为生成器(generator),跟普通函数不同的是,生成器是一个返回迭代器的函数;只能用于迭代操作,更简单点理解生成器就是一个迭代器。
不同之处:就是协同程序(可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的地方从程序离开的地方继续或者重新开始)

重点:调用一个生成器函数,返回的是一个迭代器对象。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

案例:生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/python3
#功能:生成器yield
import sys

#案例1:
def gener():
print("生成器被执行!",end=" ")
yield 1 #运行第一next 暂停在这里
yield 2 #运行第二next 显示二

my = gener()
next(my) # 成器被执行! 2
next(my) # 2


#方法2:
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
#当 counter == 10 结束(即算出10次数)
if (counter > n):
return
yield a #生成器进行返回
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成

while True:
try:
print(next(f), end=" ") #一次返回一个斐波那契数列 0 1 1 2 3 5 8 13 21 34 55
except StopIteration:
sys.exit()


#方法3:for循环会自动解析Stopiteration异常并结束
def fbli():
a = 0
b = 1
while True:
a, b = b, a+b
yield a

for each in fbli(): #each 及是 返回生成器 a的值
if each <= 55:
print(each,end=" ")
else:
break

########## 执行结果 ##########
# 1 2 3 5 8 13 21 34 55

9.Python 函数

9.1 函数定义语法

函数能提高应用的模块性,和代码的重复利用率可以进行自我调用,用户自己建立的函数叫用户自定义函数;
函数function,对象object,模块moudule。

函数与过程: 过程(procedure)是简单的,特殊并且没有返回值的,一般的编程语言都把函数和过程分开。
但Python事实上只有函数没有过程,函数是有返回值的,当函数中无return语句返回的时候,将返回None类型。但Python可以返回多个值、利用列表【多种类型共存】或者元组;

Q:如何定义一个函数?
A:以下是简单的规则:
1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (),函数内容以冒号起始,并且缩进。
2.任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
3.函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。即 ‘’’函数说明’’’
4.return [ 表达式 ] 结束函数,选择性地返回一个值给调用方,如果不带表达式的return相当于返回 None。

函数语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#.__doc__ (函数的默认属性,他是一个特殊的属性,特殊属性格式就是这样)
def 函数名(形参列表):
'函数文档 :通过 函数名.__doc__调用'
函数体


#(形参) formal parameters
#(实参) actual parameters
def first(name="default"):
'函数定义过程中name是形参' #因为ta只是一个形式,表示占据一个参数位置。
print(name,"这时候name的值是实参,因为他是具体的参数值!")

>>> def hello():
print("hello world") #由于这里没有return 语句,将返回None
>>> temp = hello() #将函数的值返回给temp
hello world
>>> temp #但是temp并没有return返回值
>>> print(temp)
None #Print-Temp时候返回了None类型
>>> type(temp)
<class 'NoneType'>


>>> def back():
return ["Python","Flash", 3.1415926]
>>> back()
['Python', 'Flash', 3.1415926] #返回列表

>> def back():
return "Python","Flash", 3.1415926
>>> back()
('Python', 'Flash', 3.1415926) #返回元组

默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

函数实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3
#功能:实现函数功能

def fun(num1,num2):
'函数功能:求出两个数之和' #通过 函数名.__doc__调用函数文档
return num1 + num2 #用return返回参数或者程序运行的结果

def saypython(name='小甲鱼',words="改变时间"): #设置默认参数,当未给函数赋值的时候显示
'函数文档:我们的心声'
print(name + ' 想 ->' + words)

print("1 + 2 =",fun(1,2))
print("函数说明:(",fun.__doc__,end=")\n-------------")
print("我",saypython('weiyigeek','改变世界')) #由于无return语句则返回none

saypython('weiyigeek','改变世界')
saypython() #采用函数默认参数,便可以不带参数运行,因为有内置可选参数 name='小甲鱼',words="改变时间"

print("函数说明:(",fun.__doc__,end=")\n")

Python函数定义案例

Python函数定义案例

9.2 函数参数详述

python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
  • 可变类型:类似 c++ 的引用传递,如列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

以下是调用函数时可使用的正式参数类型:

  • 必需参数, def printme(argv,argv1)
    = 关键字参数,函数调用使用关键字参数来确定传入的参数值(无需顺序输入,采用关键字即可) printme(argv1= 1024,argv = 1)
  • 默认参数,def printme(argv = 1024)
  • 不定长参数,需要一个函数能处理比当初声明时更多的参数 (重点)

可变参数运用在不确定有多个参数之间:
(1)加了单个星号 形参名,如(params)会打包成为元组(tuple),如果在函数调用时没有指定参数,它就是一个空元组,我们也可以不向函数传递未命名的变量。
(2)加了两个星号 形参名,如(params)会以字典(dict)的形式导入

函数参数案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/python3
#功能:函数参数
#例如:其实PRINT()就自带收集参数*Objects
#print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

#/*不可变对象**/
def ChangeInt(a):
a = 10
print("(不可变)函数内:",a) #结果是 10

b = 2
ChangeInt(b)
print("(不可变)函数外:",b,end="\n\n") #结果是 2

#/*可变对象**/
def changeme(mylist):
mylist.append([1,2,3,4]) #这时候传入列表已经被改变了
print("(可变)函数内取值 :",mylist)
return
mlist = [6,6,6]
changeme(mlist)
print("(可变)函数外取值 :",mlist) #列表已改变

#!/*** 可变参数(*) 与 关键字参数 **/
def test(*params,exp="weiyi"):
print("参数长度 :",len(params)," 第二个参数:",params[1],"Name :",exp)
for var in params:
print(var,end=",")
return 0

test(1,"爱您",1024,1,exp='weiyigeek')

#!/*** 可变参数(**) **/
def printmm(arg1,**vardict):
'函数文档:形式参数为字典类型'
print("\n\n输出 arg1:",arg1)
print("输出 vardict 字典 :",vardict)

printmm('test',a=1,b=2,c=3)

#!/*** 单个星号的使用 (注意)**/
def star(a,b,*,c):
print("a :",a ," b:",b ,' c:', c)

star(1,2,c=1024) #c必须进行指定关键字传入值,否则会报错

Python函数参数案例

Python函数参数案例

注意事项:
1) Python一切皆对象,严格意义上我们不能说是值传递还是引用传递,我们应该说不可变对象和可变对象。
2) 声明函数时,参数中星号 * 可以单独出现,但是星号后的参数必须用关键字传入。

9.3 匿名函数

python 使用 lambda 来创建匿名函数,所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 表达式好处:使得代码更加精简,不需要考虑命名控制,简化代码可读性。

Q:如何建立一个匿名函数?
A :lambda 只是一个表达式,函数体比 def 简单很多。
lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [ ,arg2,…..argn ]]:expression

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/python3
#功能:使用匿名函数

#函数定义
sum = lambda arg1,arg2: arg1 + arg2
sum.__doc__ = '函数文档'

#调用匿名函数
print("1 + 99 相加后的值 :",sum(1,99))
print(sum.__doc__)


#进阶用法和BIF内置函数filter/map的使用
#匿名函数进阶 (设置过滤函数,返回可以不可以整除2的数值)
show = list(filter(lambda x: x % 2,range(10)))
print(show)

#进行map映射显示被%2整除后的结果。
show = list(map(lambda x:x % 2,range(10)))
print(show)

Python字典案例

Python字典案例

注意事项:
1) lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
2) lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
3) 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

9.4 函数变量作用域

Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的,变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称,作用域一共有4种分别是:

  • 局部变量(Local Variable),只有在函数内部中进行访问使用。
    E (Enclosing) 闭包函数外的函数中
    
  • 全局变量(Global Varable), 在可以在整个程序范围内访问。
    B (Built-in) 内置作用域(内置函数所在模块的范围)
    

以的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

1
2
3
4
5
6
g_count = 0  # 全局作用域
def outer():
o_count = 1 # 闭包函数外的函数中
def inner():
i_count = 2 # 局部作用域
#内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。

如果在函数中修改全局变量便会出现,新建一个与全局变量相同名字的局部变量,并将全局变量的值赋给它,修改得其实是局部变量的值,而全局变量里面的值没有任何更改。

案例:函数作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python3
#代码功能:全局与局部变量Variable

#msg 变量定义在 if 语句块中,但外部还是可以访问的
if True:
msg = "I am from Weiyigeek"
print("\nmsg 变量定义在 if 语句块中,但外部还是可以访问的:",msg)

def discount(price,rate):
final_price = price * rate #局部变量
# print("这里试图打印全局变量old_price的值(回报错):",old_price)

local_price = 100 #定义在函数中,则它就是局部变量,外部不能访问
print("局部变量local_price :",local_price) # 100

old_price = 50
print("函数内修改后old_price的值是1 :",old_price)
return final_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入则扣率: '))
new_price = discount(old_price,rate)
print('函数外修改后的old_price的值是2 :',old_price)
print('打折后的价格 :',new_price)

Python函数作用域案例

Python函数作用域案例

注意事项:
1) 尽量不要去在函数中更改全局变量,而且慎用全局变量。
2) Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域。
3) 其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问。

9.4.1 函数变量作用域关键字

描述:Python为了保护全局变量引入了{ 屏蔽(Shadowing) },当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。

global 和 nonlocal关键字:

global关键字可以在定义的函数中更改全局变量(global variable),如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了

案例: 作用域关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python3
#功能:全局变量作用域和非全局作用域

"""global"""
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print("global:",num,end=",")
num = 123
print(num,end=",")
num += 133
fun1()
print(num)
#global: 1,123,256


"""nonlocal"""
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print("nonlocal:",num,end=" | ")
num *= 10.24
inner()
print(num,end=" | ")
outer()
print(num) #这里的num没有变化由于outer函数中没有使用global关键字
#nonlocal: 100 | 1024.0 | 256

9.5 内嵌函数和闭包

Python中函数中可以内嵌函数定义与使用,还能在全局变量不适用的时候可以考虑使用闭包更稳定和安全。
容器(container),比如前面的所有数组(array)=列表(list),元组(tuple)

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/python3
#功能:内嵌函数与闭包使用

#""" 内嵌函数 """
def fun1():
print("Fun1 主函数被调用")
def fun2():
print("Fun2 内嵌函数正在被调用\n")
fun2() #内部函数(内嵌函数),只能由fun1()调用

fun1()



#"""闭包"""
def funX(x):
def funY(y):
return x * y
return funY

i = funX(8)
print("i的类型 :",type(i))
print("8 * 5 =",i(5)) # 40 由于前面已经赋值给x了,后面得就给了y=5.
"""
#类似于:
def funX(x):
def funY(y):
return x * y
return funY(2)
>>> funX(3)
6
"""



#"""闭包进阶(采用类似于数数组的方式 -- 列表(传入的是地址))"""
def demo1(arg):
x = [arg]
def demo2():
#采用 nonlocal 关键字也行
x[0] **= x[0] #采用这样的方式进行取值列表 (**幂运算) | 不引用局部变量(Local variable),采用数组的方式进行暗渡成仓.
return x[0]
return demo2()

print("2 ** 2 =",demo1(2)," - 5 ** 5 =",demo1(5))

#"""一个闭包的典型案例"""
def funA():
x = 5
def funB():
nonlocal x #//把x强制表示不是局部变量local variable
x += 13
return x
return funB

a = funA() #当 a 第一次被赋值后,只要没被重新赋值,funA()就没被释放,也就是说局部变量x就没有被重新初始化。
print("第一次调用:",a(),"第二次调用:",a(),"第三次调用:",a())

Python内嵌函数和闭包

Python内嵌函数和闭包