首页 > 其他 > 详细

空间名称与作用域

时间:2021-06-30 20:56:47      阅读:22      评论:0      收藏:0      [点我收藏+]

今日内容

01.函数对象

#1. 函数可以被引用
def add(x,y):
    return x+y
>>> func = add  # >>>指向的是函数add的内存地址
>>> func(1,2)
	3
#2. 函数可以作为容器类型的元素
>>> dic = {‘add‘:add,‘max‘:max}
>>> dic
{‘add‘: <function add at 0x000002CCBF4CF0D0>, ‘max‘: <built-in function max>}
>>> dic[‘add‘](1,2) # 字典key‘add‘指向函数add的内存地址
    3
    
 # 3.函数可以作为参数传入另外一个函数
>>> def foo(x,y,func):
    return func(x,y) 

>>> foo(1,2,add)
   3
    
 # 4.函数的返回值可以是一个函数
 >>> def bar():
 >>>   return add
 >>> func = bar()
     func(1,2)
        3

02.函数嵌套

# 1 定义: 在一个函数体内,用def重新定义新的函数
# 在定义阶段,是封闭的,在调用的时候是拆解,在调用时,内部又调用其他的函数,大功能拆解成小功能
>>>def outer():
       def inner():
           print(‘innner‘)
       print(‘outer‘)
   	   inner()
  outer()
  >>outer 
  >>inner
  # inner() 会报错,因为内部函数不可见
  # 内部函数不能被外部直接使用,会抛NameError异常

# 函数嵌套小案例:
"""需求求圆的面积与周长,要求在一个函数内实现"""
from math import pi  #导入模块,pi


def circle(radius, mode=0):
    
    def perimeter(radius):   # 定义周长函数
        return 2*pi*radius
    
    def area(radius):       # 定义面积函数
        return pi*(radius ** 2)
    
    if mode == 0:           # 模式选择 0.则返回值为周长函数
        return perimeter(radius)
   	elif mode == 1:         # 模式选择 1.则返回值为面积函数
        return area(radius)

    
   res = circle(30,1)
   print(res)  ##2827.4333882308138

03.名称空间

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren‘t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you‘re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it‘s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let‘s do more of those!


Namespaces are one honking great idea  # 由此可见名称空间的重要性
# 名称空间即存放名字与对象映射/绑定关系的地方

3.1内部名称空间(built-in names)

python自带的名称,比如内建函数
生命周期: 伴随python解释器的启动/关闭而产生/回收
>>> abs
<built-in function abs> # build in 内建

3.2全局名称空间(global names)

顶级的名字(顶格写的变量名)模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
生命周期:伴随python文件的开始执行/执行完毕而产生/回收

import os   # 模块名 os

x = 1   # 变量名 x

if x == 1: 
    y = 2  # 变量名y

def foo(x): # 函数名foo
    y = 1 
    def bar()
     pass
    
class Bar: # 类名Bar
    pass

3.3局部名称空间(local names)

函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
生命周期: 调用即产生,结束即退出
>>>def foo(x):
    y = 3 # 调用函数时,才会被执行代码,名字x和y都存放于该函数的局部名称空间中

3.4名称空间的查找顺序

技术分享图片

查找顺序:局部名称空间>>全局名称空间>>内置名称空间

名称空间嵌套关系是在函数定义时已经生成,与调用无关

# 例如
def foo():
    print(int)  # 在定义阶段名称空间已经生成,局部没有,向上查找,全局空间执行 int =100, 如果int没有被定义的话,再向上查找,内置空间,你将看到的是 <class ‘int‘>

def bar():
    int = 666
    foo()
    
int = 100  #  

bar()  
>>> 100

全局变量与局部变量

全局变量可以在整个程序范围内访问,局部变量只能在其被声明的函数内部访问
total = 0   # total 为全局变量
def sun(x,y):
	total = x + y
     return total
    
当内部想要修改外部的变量时,就要使用global和nonlocal关键字
global 和 nonlocal 关键字

# global
num = 1
def func():
   	global num  # 声明global关键字 修改全局变量
    print(num)
    num = 123
    print(num)
>>>  func()
>>> print(num)
 1
 123
 123
# 可以看到通过使用global 改变了全局变量的值



# nonlocal 

# nonlocal关键字: 声明一个名字是来自于外层函数,如果外层没有不会找到全局,会报错
x = 1
def f1():
    x = 2
    print(x)
   def f2():
       nonlocal x
	   x = 3
   f2()
   print(x)

f1()
print(x)
2
3
1
# nonlocal 可以看到全局变量并没有改变 nonlocal改变的是函数嵌套内部的值

作用域

作用域就是一个 Python 程序可以直接访问命名空间的正文区域。

在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。

Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

有四种作用域:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

规则顺序: L –> E –> G –> B

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

技术分享图片

闭包函数

# 闭包函数=函数对象+函数嵌套定义+名称空间与作用域

# 闭函数:定义在函数内部的函数
# 包函数: 内部函数引用了一个外层函数的名字
def foo():
    x = 111
    def wrapper():
        print(x)
     return wrapper
f = foo()
f()
print(f)
>>>
111
<function foo.<locals>.wrapper at 0x00000240C9679700>  # 打印的为f的内存地址

### 闭包的函数的作用:闭包函数是一种为函数体传参的方案

# 为函数体传参方案一:直接传参
def wrapper(x):
    print(x)
    
wrapper(1)

# 为函数体传参方案二:闭包函数
def outter(x):
    def wrapper():
        print(x)
    return wrapper
wrapper = outter()

wrapper(111) 

空间名称与作用域

原文:https://www.cnblogs.com/wzf-1314-cym-6/p/14955850.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!