Python语法基础(二)
🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
变量的作用域的分类
变量的作用域一般分为全局作用域、局部作用域、函数作用域
num1=10 # 全局作用域
def outter1():
num2 = 20 # 函数作用域,在嵌套定义的函数中,定义在外部函数中的变量
def inner1():
num3=30 # 局部作用域
不同作用域中的变量的访问权限
全局作用域:特点,在当前py的任意位置都可以被访问到。
函数作用域:特点,在嵌套定义的函数中,定义在外部函数中的变量,只能在外部函数中使用。
局部作用域:特点,只能在内部函数中被访问。
我们来看下面的这一段代码:
num1=10 # 全局作用域 特点:在当前py文件的任意位置都可以被访问到
def outter1():
num2 = 20 # 函数作用域,在嵌套定义的函数中,定义在外部函数中的变量 只能在外部函数中被访问
def inner1():
num3=30 # 局部作用域 特点:只能在内部函数中被访问
print(num3,num2,num1) # num2闭包,num1全局
inner1()
print('outter:',num2,num1)
outter1()
print("global:",num1)
如果我们这时候将所有的变量的名称都改为相同的,这个时候会发生什么呢?
我们来看下面的这一段代码。
num1=10 # 全局作用域 特点:在当前py文件的任意位置都可以被访问到
def outter1():
num1 = 20 # 函数作用域,在嵌套定义的函数中,定义在外部函数中的变量 只能在外部函数中被访问
def inner1():
num1=30 # 局部作用域 特点:只能在内部函数中被访问
print(num1,num1,num1) # num2闭包,num1全局
inner1()
print('outter:',num1,num1)
outter1()
print("global:",num1)
你看这个时候代码的运行结果,这个说明了什么呢?
这个体现出了不同作用域之间的就近原则。
也就是说,如果不同作用域中的变量的名字重名,那么当变量被访问的是时候,将采用就近的原则,并且,这几个变量虽然重名,但是相互之间却是三个不同的变量,相互之间没有任何关系。
会引入新的作用域:类、函数、模块
不会引入新的作用域:if for while try-except
if 1:
num=0
print(num)
def func1():
num1=0
print(num1)
你看,在这两个代码当中,第二个因为作用域的原因,所以调用会报错。
global的使用
n1=10
def func1():
n1=20
func1()
print(n1)
大家可以分析一下这里打印出来的结果为什么会是10,如果分析错误的话,需要重新返回去看看我们上面讲到的知识点。
接下来,我们看一下下面的这一段代码
n1=10
def func1():
n1 += 20 # 还没有赋值就直接进行了调用
func1()
print(n1) # 10
在这段代码中,func1的执行是会报错的,是因为其中的n1还有被复制就进行了调用。
那么,这个有什么方法可以解决呢?
方式一、表示不同的变量
n1=10
def func1():
n1 = 10
n1 = n1 + 20 # 还没有赋值就直接进行了调用
print("内部:",n1)
func1()
print("外部:",n1) # 10
方式二、表示相同的变量
#解决方案二、,表示相同的变量
n1=10
def func1():
global n1 # 声明n1变量来自于全局变量
n1 += 20 # 还没有赋值就直接进行了调用
print("内部:",n1) #30
func1()
print("外部:",n1) # 30
n1=10
def func1():
global n1
if n1:
n1=25
print('内部: ',n1)
func1()
nonlocal只能使用在嵌套定义的函数中,发生在局部作用域和函数作用域之间
# 1.
def outter1():
name='abc'
def inner1():
name='123'
name +='abc'
print('局部:',name)
inner1()
print("函数:",name)
outter1()
# 2.
def outter1():
name="asd"
def inner1():
# nonlocal x : 声明x变量来自于函数作用域
nonlocal name
name +='abc'
print('局部:',name)
inner1()
print("函数:",name)
outter1()
函数生成器
# 2. 函数结合yield,定义函数生成器
def func1():
yield 10
yield 20
yield 30
r2=func1()
print(r2) # <generator object func1 at 0x00000190CABD89E0>
def func3():
for i in range(10):
yield i**2
r3=func3()
print(r3)
上面的这两个都是函数生成器的定义,那么定义了函数生成器之后,我们应该怎么访问生成器中的元素呢?
方式一、
def func3():
for i in range(10):
yield i**2 # 预放入的数据,不占用内存
r3=func3()
print(r3)
print(list(r3))
方式二、
# 方式二
for els in r3:
print(els)
方式三、
# 方式三
print(next(r3))
print(next(r3))
print(next(r3))
print(next(r3))
生成器如果把数据都访问完,再获取就会报错。
for els in r3:
print(els)
print(next(r3))
print(next(r3))
print(next(r3))
print(next(r3))
这个代码会报错,报错内容: StopIteration
好了,这节课的内容,我们就到这里,下节课再见。