[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-可迭代的对象,比如列表、字典、元组等等。
案例:数据类型转换函数使用
代码语言:javascript复制#!/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数据类型转换函数使用
6.操作符以及优先级
Q: 什么是运算符? A:让变量进行加减乘除四则运算;
运算符及其优先级:
- 算术运算符
- 右移/左移运算符
- 位运算符
- 比较(关系)运算符
- 等于运算符
- 赋值运算符
- 身份运算符
- 成员运算符
- 逻辑运算符
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各种操作符
代码语言:javascript复制#!/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各种操作符案例
注意事项: 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
分支语法:
代码语言:javascript复制# 方式1.
if 表达式:
执行语句
elif 表达式:
执行语句
else:
执行语句
# 方式2.三元(三目)操作符
# Python 是一种极简主义的编程语言,它没有引入? :这个新的运算符,而是使用已有的 if else 关键字来实现相同的功能。
# 如果条件为真时候将x值赋给small,为假时候将y值赋给small
x if 条件 else y
# else 语句
1) else 语句跟 if 语句搭,构成“要么怎样,要么不怎样”的语境
2) else 语句跟 for / while 语句搭,构成“干完了能怎样,干不完就别想怎样”的语境
2) else 语句跟 try 语句搭构成“没有问题,那就干吧”的语境
注意事项: 1) 由于Python中无{}包含代码块,而是采用缩进的方式来判别执行的代码块; 2) 与for/while语句搭配时候,只有在循环正常执行完成后才会执行 else 语句块的内容 3) 三目运算符是可以嵌套, 但需要注意 if 和 else 的配对使用。
代码语言:javascript复制a if a > b else c if c>d else d
a if a > b else ( c if c>d else d )
7.1.2 循环语句:while , for..else…
代码语言:javascript复制退出循环关键字:break,continue,及其循环语法:
while (表达式条件):
为真则执行代码块
else:
语句为 false 时执行该 else 的语句块:
for 变量 in 表达式:
循环体
else:
它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。
案例:条件控制于循环语句
代码语言:javascript复制#!/usr/bin/python3
#coding:utf-8
#功能:分支与循环
#-----------if 语句-----------------
guess = 8
temp = int(input("请输入一个1-10数值:"))
if guess == temp:
print("恭喜您,输入的数值刚好")
elif guess > temp:
print("太遗憾了,输入的数值小于它")
else:
print("太遗憾了,输入的数值大于它")
#【实例】使用 Python 三目运算符判断
x,y = 1,3
print("#三元(三目)运算符 :",end="")
print( x if x > 3 else y )
#【实例】使用 Python 三目运算符判断两个数字的关系:
a = int( input("Input a: ") )
b = int( input("Input b: ") )
print("a大于b") if a>b else ( print("a小于b") if a<b else print("a等于b") )
#------------while 语句---------------
# Fibonacci series: 斐波纳契数列 (两个元素的总和确定了下一个数)
a,b = 0,1
while b < 10:
print(b,end=",")
a,b = b, a b
print("nn")
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条件控制于循环案例
7.1.3 空语句:pass
Python pass是空语句,是为了保持程序结构的完整性,pass 不做任何事情,一般用做占位语句,如下实例:
代码语言:javascript复制while True:
pass # 等待键盘中断 (Ctrl C)
#最小的类:
class MyEmptyClass:
pass
8.迭代器与生成器
8.1 迭代器 iter
迭代是Python最强大的功能之一是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象;迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,且只能往前不会后退。 迭代器参数:列表/字典
迭代器有两个基本的方法:iter() 和 next()。
创建一个迭代器,使用需要在类中实现两个方法 iter() 与 next() ;并且iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成,防止出现无限循环的情况。
案例:迭代器(魔术方法)
代码语言:javascript复制#!/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迭代器案例
8.2 生成器 yield
使用yield的函数被称为生成器(generator),跟普通函数不同的是,生成器是一个返回迭代器的函数;只能用于迭代操作,更简单点理解生成器就是一个迭代器。 不同之处:就是协同程序(可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的地方从程序离开的地方继续或者重新开始)
重点:调用一个生成器函数,返回的是一个迭代器对象。 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
案例:生成器
代码语言:javascript复制#!/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。
函数语法:
代码语言:javascript复制#.__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) #返回元组
默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
函数实例:
代码语言:javascript复制#!/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函数定义案例
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)的形式导入
函数参数案例:
代码语言:javascript复制#!/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="nn") #结果是 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("nn输出 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函数参数案例
注意事项: 1) Python一切皆对象,严格意义上我们不能说是值传递还是引用传递,我们应该说不可变对象和可变对象。 2) 声明函数时,参数中星号 * 可以单独出现,但是星号后的参数必须用关键字传入。
9.3 匿名函数
python 使用 lambda 来创建匿名函数,所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。 lambda 表达式好处:使得代码更加精简,不需要考虑命名控制,简化代码可读性。
Q:如何建立一个匿名函数? A :lambda 只是一个表达式,函数体比 def 简单很多。 lambda 函数的语法只包含一个语句,如下: lambda [arg1 [ ,arg2,…..argn ]]:expression
案例:
代码语言:javascript复制#!/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字典案例
注意事项: 1) lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 2) lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。 3) 虽然lambda函数看起来只能写一行,却不等同于C或C 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
9.4 函数变量作用域
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的,变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称,作用域一共有4种分别是:
局部变量(Local Variable),只有在函数内部中进行访问使用。
代码语言:javascript复制E (Enclosing) 闭包函数外的函数中
全局变量(Global Varable), 在可以在整个程序范围内访问。
代码语言:javascript复制B (Built-in) 内置作用域(内置函数所在模块的范围)
以的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
代码语言:javascript复制g_count = 0 # 全局作用域
def outer():
o_count = 1 # 闭包函数外的函数中
def inner():
i_count = 2 # 局部作用域
#内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。
如果在函数中修改全局变量便会出现,新建一个与全局变量相同名字的局部变量,并将全局变量的值赋给它,修改得其实是局部变量的值,而全局变量里面的值没有任何更改。
案例:函数作用域
代码语言:javascript复制#!/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函数作用域案例
注意事项: 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 关键字了
案例: 作用域关键字
代码语言:javascript复制#!/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)
案例:
代码语言:javascript复制#!/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内嵌函数和闭包