前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >可变长参数、函数的嵌套、名称空间和作用域学习笔记

可变长参数、函数的嵌套、名称空间和作用域学习笔记

作者头像
GH
发布2022-05-10 15:56:58
3560
发布2022-05-10 15:56:58
举报

目录

写在博客的开头

nick说:人生疾苦唯有自救,这是你相信IT的最后一次机会。这个时候必须得逼自己一把,只有对自己够狠才能慢慢强大。昨天看一哥们在博客上说每天大喊一遍python第一java第二,python大法无所不能,给自己以一个乐观积极的态度好好学习天天向上。加油,希望我们每一个人都不负光阴。

可变长参数

形参名

代码语言:javascript
复制
def f1(*args):#调用时有多少个位置实参就接收多少个
    print(args)#\*args(约定俗成的),用元组接收多余的位置实参

形参

代码语言:javascript
复制
def f1(**kwargs):
    print(kwargs)#用字典接收多余的关键字实参

以上内容很important,以下内容仅作了解(Nick说以后很少用到)

实参

代码语言:javascript
复制
def f1(a,b,c,d,e,f,g):
    print(a,b,c,d,e,f,g)
    
    lt = [1,2,3,4,5,6,7]
    f1[*lt]#\*lt把列表中的元素打散成位置实参一次传给位置形参(这个过程其实就是解压缩)

实参

代码语言:javascript
复制
def f1(z,b):
    print(z,b)
dic = {'z':,'b':2}
f1(**dic)#**dic把字典打散成关键字实参然后传给函数f1

函数对象

Python中一切皆对象,函数是第一类对象,即函数可以被当作数据处理。

代码语言:javascript
复制
def func():
    print('from func')
    
prnit(func)
<function func at 0x10af72f28>

一、函数对象的四大功能

  1. 引用
代码语言:javascript
复制
x = 'hello nick'
y = x

f = func#这么做的的原因是:这样f()和func()就是同一个函数了
print(f)
<function func at 0x10af72f28>

2. 当做参数传给一个函数

代码语言:javascript
复制
len(x)

def foo(m):
    m()
foo(func)#func是一个函数名,将func作为实参传给foo这个函数,形参m用于接收func,执行到foo函数体里面就得到了func()实现了对func函数的调用。 
from func

3. 可以当做函数的返回值

代码语言:javascript
复制
def foo(x):
    return x

res = foo(func)
print(res)
res()#func被return回来赋给res从而实现了对func函数的调用
<function func at 0x10af72f28>
from func

4. 可以当作容器类型的元素

代码语言:javascript
复制
l = [x]

function_list = [func]
function_list[0]()#这个就很叼了,在调用登录注册等多个函数时把函数名作为字典的value,然后通过这种方法去调用函数贼方便。
from func

练习

代码语言:javascript
复制
def register():
    print('register')
def login():
    pass
def withdraw():
    pass
def shoppong():
    print('shopping')
func_dict = {
    '1':register,
    '2':login,
    '3':withdraw,
    '4':shopping,
}
print('''
1 注册
2 登录
3 提现
4 购物
''')
while Ture:
    choice = input('请选择你需要的功能(输入q退出):')
    if choice == 'q':
        break
     func_dict[choice]()#函数当做容器类型的元素

函数的嵌套

所谓嵌套就是在函数内部再定义函数,不过函数内部定义的函数,无法在函数外部使用。

代码语言:javascript
复制
def f1():
    def f2():
        print('from f2')
    f2()

f2()  
# NameError: name 'f2' is not defined

这个就可以使用:

代码语言:javascript
复制
def f1():
    def f2():
        print('from f2')
    f2()

f1()
from f2

函数嵌套的调用

如下面一个比较四个数大小得出最大值的函数

代码语言:javascript
复制
def compare_1(x,y):
    if x>y:
        return x
    else:
        return y
def compare_2(a,b,c,d):
    res1 = compare_1(a,b)
    res2 = compare_1(res1,c)
    res3 = compare_1(res2,d)#牛掰哦这种比较方法
        return res3
#compare_2(1,2,3,4)
print(compare_2(1,2,3,4))
4

名称空间和作用域

一、名称空间

名称空间(name spaces):在内存管理那一章节时,我们曾说到变量的创建其实就是在内存中开辟了一个新的空间。但是我们一直在回避变量名的存储,其实在内存中有一块内存存储变量名与变量间的绑定关系的空间,而这个空间称为名称空间。

1.1 内置名称空间

内置名称空间:存放Pyhton解释器自带的名字,如int、float、len

生命周期:在解释器启动时生效,在解释器关闭时失效。

1.2 全局名称空间

全局名称空间:除了内置和局部的名字之外,其余都存放在全局名称空间。

生命周期:在文件执行时生效,在文件执行结束后失效。

1.3 局部名称空间

局部名称空间:用于存放函数调用期间函数体产生的名字,如下面代码的f2

生命周期:在文件执行时函数调用期间时生效,在函数执行结束后失效。

代码语言:javascript
复制
def f1():
    def f2():
        print('from f2')
    f2()
f1()
1.4 加载顺序

由于.py文件是由Python解释器打开的,因此一定是在Python解释器中的内置名称空间加载结束后,文件才开始打开,这个时候才会产生全局名称空间,当文件内某一个函数被调用时,才会产生局部名称空间,因此名称空间的加载顺序为:内置》全局》局部》。

1.5 查找顺序

由于名称空间是用来存放变量名与变量值之间的绑定关系的,所以但凡要查找名字,一定要从三者之一找到,查找顺序为:

从当前所在的位置开始查找,如果当前所在的位置为局部名称空间,则查找顺序为:局部》全局》内置。

代码语言:javascript
复制
x = 1
y = 2
len = 100

def func():
    y = 3
    len = 1000
    print(f"y:{y}")
    print(f"len:{len}")
   
func()    
y: 3
 len: 1000
def func():
    
    printx
x = 10
func()
10

二、作用域

域指的是区域,作用域就是作用的区域。

2.1 全局作用域

全局作用域:全局有效,全局存活,包含内置名称空间和全局名称空间。

代码语言:javascript
复制
#全局作用域
x = 1
def bar():
    print(x)
bar()
1
2.2 局部作用域

局部作用域只包含局部名称空间。

代码语言:javascript
复制
def f1():
    def f2():
        def f3():
            print(x)
        x = 2
        f3()
    f2()
f1()
2
2.3 注意点

作用域关系在函数作用阶段就固定死了,与函数的调用无关。

代码语言:javascript
复制
# 作用域注意点
x = 1


def f1():  # 定义阶段x=1
    print(x)


def f2():
    x = 2
    f1()

f2()
1

很绕的一个例子,画个图看一下:

程序运行的时候内存空间的开辟如图所示,所以当f1()运行的时候,程序会先在f1()的局部作用域内找x的值,找不到就去全局找而不是去f2()的作用域内找。再看下面一个例子:

代码语言:javascript
复制
x = 1
def f2():
    x = 2

    def f1():  # 定义阶段x=1
        print(x)
    f1()
f2()
2

这个f1执行完就回去f2找x的值,因为f1的作用域在f2里面。

2.4 函数对象+作用域应用
代码语言:javascript
复制
# 作用域应用
def f1():
    def inner():
        print('from inner')
    return inner

f = f1()  # 把局部定义的函数放在全局之中

def bar():
    f()

bar()#相当于f1()(),相当于inner()
from inner

三、补充知识点

3.1 global关键字(尽量少用,Nick说容易懵逼)

修改全局作用域中的变量。

代码语言:javascript
复制
x = 1


def f1():
    x = 2

    def f2():
        #         global x  # 修改全局
        x = 3
    f2()


f1()
print(x)
1
代码语言:javascript
复制
x = 1


def f1():
    x = 2

    def f2():
        global x  # 修改全局
        x = 3
    f2()


f1()
print(x)
3
3.2 nonlocal关键字(最好不要使用,容易把自己弄懵逼)

修改作用域中的变量。

代码语言:javascript
复制
x = 1


def f1():
    x = 2

    def f2():
        #         nonlocal x
        x = 3

    f2()
    print(x)


f1()

2

代码语言:javascript
复制
x = 1


def f1():
    x = 2

    def f2():
        nonlocal x
        x = 3

    f2()
    print(x)


f1()

3

3.3 注意点(very important)
  1. 可变数据类型可以打破上述一切规则。
代码语言:javascript
复制
lt = [10]


def f1():
    lt.append(12)
    lt[0] = 11


f1()

print(lt)

[11, 12]

  1. 在局部如果想修改全局的不可变类型,需要借助global声明,声明为全局变量,即可直接修改。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在博客的开头
  • 可变长参数
    • 形参名
      • 形参
        • 实参
          • 实参
          • 函数对象
            • 一、函数对象的四大功能
            • 函数的嵌套
            • 函数嵌套的调用
            • 名称空间和作用域
              • 一、名称空间
                • 1.1 内置名称空间
                • 1.2 全局名称空间
                • 1.3 局部名称空间
                • 1.4 加载顺序
                • 1.5 查找顺序
              • 二、作用域
                • 2.1 全局作用域
                • 2.2 局部作用域
                • 2.3 注意点
                • 2.4 函数对象+作用域应用
              • 三、补充知识点
                • 3.1 global关键字(尽量少用,Nick说容易懵逼)
                • 3.2 nonlocal关键字(最好不要使用,容易把自己弄懵逼)
                • 3.3 注意点(very important)
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档