函数基础2

Posted lgh8023

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数基础2相关的知识,希望对你有一定的参考价值。

*与**在形参与实参中的应用

一.可变长指的是参数的个数不固定
站在实参的角度,实参是用来为形参来赋值的,如果实参的个数不固定,那么必须要有对应的形参能够接收溢出实参
=在形参中用*与**=

1.1在形参名前加*,
def func(x,*y):  # y=(2,3)
   print(x)
   print(y)

func(1,2,3)
func(1)
func()  #位置形参x必须被传值

示范:

def add(*nums):
   res = 0
   for num in nums:
      res+=num
      return res

res = add(1,2,3)
print(res)
1.2在形参名前加:会把溢出的关键字实参存成字典,然后赋值其后的形参名
def func(x,**y):  #y=(2,3,4)
   print(x)
   print(y)
func(1,a=111,b=222,c=333)
func(a=111,b=222,x=1,c=333)

在实参中用*与**=

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

1.3在实参前加:会把其后的值打散成位置实参
nums = [1,2,3]
func(*nums) # func(1,2,3)
1.4在实参前加:会把其后的值打撒关键字实参
dic = {"y": 111, "z": 222, "x": 333}
func(**dic)  # 333 111 222

=======在形参与实参中混用*与**

def index(x,y,z,a,b,c):
   print("index=======>",x,y,z,a,b,c)

def wrapper(*args,**kwargs):
   index(*args,**kwargs)    # args=(1, 2, 3,)   kwargs={"a":111,"b":222,"c":333}
wrapper(1,2,3,a=111,b=222,c=333)   # index(*(1, 2, 3,),**{"a":111,"b":222,"c":333})

                        #  index(1,2,3,c=333,b=222,a=111)

wrapper(1,2,3,a=111,b=222,c=333)

命名关键字形参

def func(x, y=222, *args, n=777,m, **kwargs):  # m,n必须按照关键字实参的格式为其赋值
    print(x)  # 1
    print(y)  # 2
    print(args)  # (3,4,5)
    print("m===>", m)
    print("n===>", n)
    print(kwargs)

func(1,2,3,4,5,6666666)
func(1,2,3,4,5,m=6666666)
func(1, 2, 3, 4, 5, n=88888,m=6666666, a=11, b=22, c=33)

函数对象:

函数对象指的是函数可以被当成变量去使用

def foo(): # foo = 函数的内存地址
print("from foo")

可以被赋值
f = foo
print(f is foo)
f()
可以当做参数传给一个函数

def bar(func):
   print(func)
   func()

bar(foo)
可以当成一个函数的返回值


def bar(func):
   return func

res = bar(foo)
print(res)
可以当成容器类型的元素
l = [foo]
print(l)
l[0]()

示例:

def login():
   print("登录功能.....")


def withdraw():
   print("提现功能.....")


def transfer():
   print("转账功能.....")


def recharge():
   print(‘充值功能......‘)


func_dic = {
   "1": [login, "登录"],
   "2": [withdraw, "提现"],
   "3": [transfer, "转账"],
   "4": [recharge, "充值"]
}

while True:
   print("0    退出")
   for k in func_dic:
      print(f"{k}    {func_dic[k][1]}")

   choice = input("请输入你的指令编号:").strip()

   if choice == "0":
      break
   if choice in func_dic:
      func_dic[choice][0]()
   else:
      print(‘输入的指令不存在‘)

函数嵌套:

函数的嵌套调用

def bar():
   print(‘from bar‘)


def foo():
   print(‘from foo‘)
   bar()


foo()

案例:

def max2(x, y):
   if x > y:
      return x
   else:
      return y


def max4(a, b, c, d):
   res1 = max2(a, b)
   res2 = max2(res1, c)
   res3 = max2(res2, d)
   print(res3)


max4(1, 2, 3, 4)

函数的嵌套定义

def f1():
   print(‘from f1‘)

   # f2 = 函数的内存地址

   def f2():
      print("from f2")


f1()

定义在函数内的函数特点是: 正常情况只能在函数体内调用

from math import pi


def circle(radius, mode=0):
   def perimeter(radius):
      return 2 * pi * radius

   def area(radius):
      return pi * (radius ** 2)

   if mode == 0:
      return perimeter(radius)
   elif mode == 1:
      return area(radius)


res1 = circle(3, 0)
res2 = circle(3, 1)
print(res1)
print(res2)


def func():
   x = 10
   print(x)

   def f2():
      print(‘from f2‘)

   f2()


func()

# print(x)

名称空间与作用域

名称空间: 就是存放名字的地方
1.
内置名称空间: 存放的是内置的名字, 如printinputlen
生命周期: 解释器启动则产生, 解释器关闭则销毁
2.
全局名称空间: 存放的是顶级的名字
生命周期: python程序运行时则产生, python程序结束时则销毁

x = 10


def func():
   x = 111
   print(x)


if 1:
   y = 666

局部名称空间: 函数内的名字
生命周期: 调用函数时则产生, 函数调用结束则销毁

名字的查找优先级:
从当前位置往外查找, 如果当前是在局部: 局部名称空间->全局名称空间->内置名称空间
从当前位置往外查找, 如果当前是在全局: 全局名称空间->内置名称空间

示范1:

def func():
   len = 222


# print(len)

func()
print(len)

名称空间可以理解为一层套一层的关系, 问题是嵌套关系是在函数定义阶段生成的, 还是在函数调用阶段生成的?

x = 111


def foo():
   print(x)


def bar(f):
   x = 222
   f()


bar(foo)

一个非常重要的结论: 名称空间的嵌套关系是函数定义阶段(即扫描语法时)
就固定死的, 与函数的调用位置无关

x = 111


def func():
   print(x)  # 报错
   x = 222


func()

练习

x = 0


def f1():
   x = 1

   def f2():
      x = 2
      print(x)

   f2()


f1()

len = 111

len = 111


def f1():
   len = 222


def f2():
   len = 333


f1()
f2()

全局范围 / 全局作用域: 内置名称空间 + 全局名称空间
特点: 全局存活, 全局有效
局部范围 / 局部作用域: 局部名称空间
特点: 临时存活, 局部有效

global与nonlocal
案例1

x = 10


def func(x):  # x = 10的内存地址
   x = 10
   的内存地址
   x = 20


func(x)  # func(值10的内存地址)
print(x)

案例2

x = [11, 22, 33]


def func(x):  # x = 列表[11,22,33]的内存地址

   # x = 列表[11,22,33]的内存地址

   # x=444444444444

   x[0] = 66666


func(x)  # func(列表[11,22,33]的内存地址)
print(x)

案例3

x = [11, 22, 33]


def func():
   x[0] = 66666


func()
print(x)

案例4

x = 10


def func():
   global x
   x = 22


func()
print(x)

案例5: nonlocal生命名字是来自于外层函数的(***)

x = 10


def f1():
   x = 111

   def f2():
      nonlocal x
      x = 222

   f2()
   print(x)

f1()
print(x)


















以上是关于函数基础2的主要内容,如果未能解决你的问题,请参考以下文章

逆向及Bof基础实践

20155201 李卓雯 《网络对抗技术》实验一 逆向及Bof基础

[vscode]--HTML代码片段(基础版,reactvuejquery)

20155307刘浩《网络对抗》逆向及Bof基础

20155311高梓云《网络对抗》逆向及Bof基础

20145301赵嘉鑫《网络对抗》逆向及Bof基础