Day12 function scope of this group of content

I always complain, complain Shanghai sun, high temperatures, and God gave me a 18 typhoon came, thank you, cnm
but I python people we can not lose

in such a hostile environment, there are still nine people AI exhibition composed of men and watch the teams meet on (for free lunch)
and finally burst through the baptism of heavy wind and rain.
I was told not to pack lunch.

by!
Han Han today you have not to pump myself up, ah, I cried

Today brainwashing Verse: Avoid travel to take an umbrella, typhoon weather revel.

Vararg

A variable length parameter of * (useful)

When we pass parameters to the function at the time, and if passed more than a thief arguments, but when the function definition defines only two parameters, then how to put all the parameters are accepted up?

* Can be used.

Parameter of the spill-over-all position of the argument, and then stored tuple, the tuple is then assigned to the parameters of. Note that: the parameter name convention as args.

def sum_self(*args):
    res = 0
    for num in args:
        res += num
    return res

res = sum_self(1, 2, 3, 4)
print(res)

10

This time there are a number of naughty students asked

"Oh why can not directly define the corresponding number of parameter it?"

I pass one hundred arguments go in, you go to define, 886

Second, the variable-length argument of * (garbage)

The argument ** * * value will be taken out cycling parameters, broken into position argument. After arguments whenever encountered with *, it is the position argument should be broken into a position immediately see argument.

nick: "The word used to break up good!"

def func(x, y, z, *args):
    print(x, y, z, args)
    
func(1, *(1, 2), 3, 4)

1 1 2 (3, 4)

Third, the variable length parameter ** (Somewhat)

** parameter of the spill-over-all key argument, and then store the dictionary form, then the parameters assigned to the dictionary **. Note that: ** parameter name after the convention was kwargs.

def func(**kwargw):
    print(kwargw)

func(a=5)

{'a': 5}

Fourth, the argument of variable length ** (useful wrong, useless, this is the pass dictionary, you honestly pass a dictionary just fine, do not do anything fancy)

实参中的 会将 ** 后参数的值循环取出,打散成关键字实参。以后但凡碰到实参中带 ** 的,它就是关键字实参,应该马上打散成关键字实参去看。

def func(x, y, z, **kwargs):
    print(x, y, z, kwargs)

func(1, 3, 4, **{'a': 1, 'b': 2})

1 3 4 {'a': 1, 'b': 2}

五、命名关键字形参

现在有一个需求:函数的使用者必须按照关键字实参传。

def register(x, y, **kwargs):
    if 'name' not in kwargs or 'age' not in kwargs:
        print('用户名和年龄必须使用关键字的形式传值')
        return
    print(kwargs['name'])
    print(kwargs['age'])


register(1, 2, name='nick', age=19)

nick
19

命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数。

特点:在传值时,必须按照key=value的方式传值,并且key必须命名关键字参数的指定的参数名。

def register(x, y, *, name, gender='male', age):
    print(x)
    print(age)


register(1, 2, x='nick', age=19)  # TypeError: register() got multiple values for argument 'x'

提一句,你传和接收参数的时候要加** ,记住,你在函数里面用这些东西的时候一定要把星星去掉,不然就报错了,为什么报错,你去百度吧,我也不知道。

[img](https://images.cnblogs.com/cnblogs_com/chanyuli/1515439/o_(%60@Z%7DIR0[1[~(~SX8CB)3CN.jpg)

函数对象

我们来聊聊什么是对象吧。

对象就是那种,香香软软的小姐姐,很温柔,然后说话甜甜的,还会陪你打游戏,晚上睡觉说晚安,早上说早安然后。。。。。好难过啊我靠

img

对象嘛。就是拿来用的。渣男

一、函数对象的四大功能

1、引用

x = 'hello nick'
y = x

f = func
print(f)

<function func at 0x10af72f28>

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

len(x)


def foo(m):
    m()


foo(func)

from func 这个例子我完全看不懂,看懂的人联系我,645503024 qq,表明来意,然后我无情拒绝你(想给我上一课?给老子死)

img

靠,我看懂了,原来这个和下面哪些栗子都是以第一个为基础的,我还在想 form func到底是什么东西,原来是print出来的。

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

def foo(x):
    return x

res = foo(func)
print(res)
res()

<function func at 0x10af72f28>
from func

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

l = [x]

function_list = [func]
function_list[0]()

from func

以上的内容极其重要,一定要搞懂,不然后果很严重,你会不懂。

img

函数的嵌套

讲真,这东西和if嵌套 while 嵌套 for嵌套就一样一样的

就是在函数里面在调用函数罢了!

但是有规则,函数里面定义的函数,你不能在外部调用它。

def f1():
    def f2():
        print('from f2')
    f2()

f2()
f1()

from f2

你看,明明调用了两次函数,为什么只打印一次呢,因为f2是在f1里面定义的,相当于是f1的代码块,那么f1不被调用的话,f2他能整出来吗,肯定不能啊(骄傲授课的我)!所以在f1被调用后,定义了f2,然后又通过f1里的f2()调用了它,打印了一次。

名称空间和作用域

这个是重点,也是难点,也是饭点,再见,我去吃饭了,有事漂流瓶联系我。

img

我回来了。

img

在讲解之前,先跟你们讲明白,python的规则和java是有不一样的的地方的,如果你非要钻牛角尖,你可以去隔壁csdn看有关java的博客,在这里,你必须要接受新的规则。

规则:

一、每次看我博客之前,首先默念python大法好

二、每次看我博客之前,要在心里默念啊字真帅

三、每次看我博客之前,要先洗手

四、python天下第一,java第二

五、函数内部的函数只能在函数内部调用,不能在函数外部调用

一、名称空间

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

1.1内置名称空间

用来存放python解释器自带的名字,如int 啊 float 啊 str 啊之类的关键字

python解释器启动的时候,就会创建,关闭的时候就会销毁。

1.2全局名称空间

除了内置和局部,其他的都为全局。

在文件执行的时候生效,文件执行结束之后就是失效了。

x = 1  #全局变量


def func():
    z=1    #局部变量
    pass

1.3局部名称空间

用来存放函数调用期间函数体产生的名字,如在函数里面定义的函数,局部变量

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

46名称空间与作用域-简单.png?x-oss-process=style/watermark

1.4加载顺序

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

1.5查找顺序

由于名称空间是用来存放变量名与值之间的绑定关系的,所以但凡要查找名字,一定是从三者之一找到,查找顺序为:
从当前的所在位置开始查找,如果当前所在的位置为局部名称空间,则查找顺序为:局部--》全局--》内置。

x = 1
y = 2
len = 100


def func():
    y = 3
    len = 1000
    print(f"y: {y}")
    print(f"len: {len}")
    # print(a)  # NameError: name 'a' is not defined
    func()

y: 3
len: 1000

x = 1


def func():
    print(x)


x = 10
func()

10

二、作用域

全局作用域

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

# 全局作用域
x = 1


def bar():
    print(x)


bar()

1

2.2 局部作用域

# 局部作用域
def f1():
    def f2():
        def f3():
            print(x)
        x = 2
        f3()
    f2()


f1()    

2

2.3注意点(都给我注意点啊)

作用域关系在函数定义阶段就固定死了,与函数的调用无关。(就是说定义好的最大)

# 作用域注意点
x = 1


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


def f2():
    x = 2
    f1()


f2()

1

三、补充知识点(最好别用)

3.2global关键字

修改局部作用于中的变量

x = 1


def f1():
    x = 2

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


f1()
print(x)
1
x = 1


def f1():
    x = 2

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


f1()
print(x)
3

3.2 nonlocal关键字

x = 1


def f1():
    x = 2

    def f2():
        #         nonlocal x
        x = 3

    f2()
    print(x)


f1()
2
x = 1


def f1():
    x = 2

    def f2():
        nonlocal x
        x = 3

    f2()
    print(x)


f1()
3

3.3 注意点

lis = []


def f1():
    lis.append(1)


print(f"调用函数前: {lis}")
f1()
print(f"调用函数后: {lis}")
调用函数前: []
调用函数后: [1]

总结,你如果要改变量值,那你就用可变类型去定义变量。别用不可变类型,也不建议使用以上的两个方法,因为多使用的情况下极易报错。为什么呢

因为nick上课玩这个的时候报错了。很刺激

Guess you like

Origin www.cnblogs.com/chanyuli/p/11333212.html