Python之拆包(函数形参中关键字参数、命名关键字参数、函数返回值、字典、列表、元组、字符串)

  • Post author:
  • Post category:python


2022.4.7

拆包之前一定有装包的过程

比如函数参数的装包就是在传递实参时直接进行装包了,输出时带*对原参数进行拆包

拆包可以理解为将参数的值取出来

关于拆包的重要例子:


函数参数的拆包


关键字参数拆包

def run(a,*args):
    #第一个参数传给了a
    print(a)
    # args是一个元组,里面是2和3两个参数
    print(args)
    # *args是将这个元组中的元素依次取出来
    print("对args拆包")
    print(*args) # *args 相当于 a,b = args
    print("将未拆包的数据传给run1")
    run1(args)
    print("将拆包后的数据传给run1")
    run1(*args)
 
def run1(*args):
    print("输出元组")
    print(args)
    print("对元组进行拆包")
    print(*args)
 
run(1,2,3) #后面的2和3

输出

关键字参数拆包

1.形参中的

args其实真正接收数据的args,它是一个元组,把传进来的数据放在了args这个元组中。

2. 函数体里的args依然是那个元组,但是

args的含义就是把元组中的数据进行拆包,也就是把元组中的数据拆成单个数据。

3. 对于args这个元组,如果不对其进行解包,就将其作为实参传给其它以*args作为形参的函数时,args这个元组会看看作一个整体,作为一个类型为元组的数据传入。

命名关键字拆包

def run(**kwargs):#传来的 key = value 类型的实参会映射成kwargs里面的键和值
       # kwargs是一个字典,将未命名参数以键值对的形式
       print(kwargs)
       print("对kwargs拆包")
       #  此处可以把**kwargs理解成对字典进行了拆包,{"a":1,"b":2}的kwargs字典又
       # 被拆成了a=1,b=2传递给run1,但是**kwargs是不能像之前*args那样被打印出来看的
       run1(**kwargs)
       #print(**kwargs)
   def run1(a,b): #此处的参数名一定要和字典的键的名称一致
      print(a,b)
 
run(a=1,b=2)

输出

命名关键字拆包

总结:

  1. *args作为形参时是用来接收多余的未命名参数,而**kwargs是用来接收key=value这种类型的命名参数,args是元组,kwargs是字典。
  2. *和**在函数体中除了拆包之外,并没有什么卵用。


函数返回值拆包



return后面的数据其实就是一个省略了小括号的元组

(如果没有指定输出类型的话)


一定注意是对返回值拆包,如果函数内没有return函数,仅仅有print,是无法进行拆包的,因为函数无任何返回值



函数的拆包针对的是 return后的值

def shiyan1():
    #return 1,2
    return '外部','内部'#返回值可以是字符串
shiyan1()#无输出 实现对函数的调用 并得到返回值
#此时若对函数拆包,可得到函数的返回值
a,b = shiyan1()
print(a,b)#输出 12

def shiyan2():
    print(1,2)
shiyan2()#输出 12
a,b = shiyan2()
print(a,b)#报错 输出的不是一个迭代器
# TypeError: cannot unpack non-iterable NoneType object

举个例子解释

def func1():
	print("这是外部函数")#第一步执行
	def func2():#第三步执行
		print("这是内部函数")
	return func2()#第二步执行  return实现对func2()函数的调用
    #return func2#报错 IndentationError: unindent does not match any outer indentation level
func1()
#print(func1)#输出 <function func1 at 0x000002A095C8F4C0>
f = func1
print(f)#<function func1 at 0x000001FB7ADFF4C0>
f1 = func1()
#func1()是对函数的调用,由于函数没有返回值,仅有输出值,而输出值不是迭代器,无法进行赋值操作
#此代码相当于 调用func1()函数 并试图将其赋值给变量f 由于函数输出值不是迭代器 无法赋值 
#又相当于 调用func1()函数 命名f新变量 且f未有任何赋值操作 所以下行代码 f输出为None
#输出 这是外部函数 这是内部函数
print(f1)#输出 None
f2,f3 = func1()#此语句报错
#由于函数返回值是内部函数,内部函数本身无任何返回值,所以无法对函数拆包
def test():
    print('ceshi')
    return 'shiyan'
test()#输出 shiyan
#x = test() #输出 ceshi 为什么这条代码也会输出结果
print(test())#输出 shiyan

def function2():
    return {"key1": 1, "key2": 2, "key3": 3}
print(function2())
a,b,c = function2()#直接对函数返回值进行拆包
print(a,b,c)#对字典拆包的返回值是keys
#一定注意 字典是无序的
print(type(function2()))#输出 <class 'dict'>
for values in function2().values():
    print(values)#输出字典的每个key对应的values

x = function2()
print(x)
print(x.values())#取出全部的values
# 输出dict_values([1, 2, 3]) 将所有values打包为一个元组
print(list(x.values()))#list() 语句可以将元组 转换为列表
for item in x.items():
    print(item[0])#逐个输出全部的key值
    print(item[1])#逐个输出全部的values值
for k,v in x.items():
    print(k)
    print(v)
for k,v in function2().items():
    print(k)


元组的拆包


第一种方式:

通过命名变量的方式 要求变量个数必须与元组内个数相同

一般在要获取元组的值时使用

tup = (1, 2, 3)
a, b, c = tup  # 要求元组内的个数与接收的参数个数相同
print(a, b, c) 输出 1 2 3

第二种方式

一般在函数调用时使用

print(*tup)  # 使用*进行拆包,结果同上
输出 1 2 3
注意: a, b, c = *tup 这种写法是错误的

函数调用时可以直接

拆包元组

作为函数的实参

关于列表的拆包看以下例子

lis = (1, 2, 3, 4, 5, 6)
func(*lis)  # 回应上面方式二的使用情况

一个重要的例子:

stars = ("黎明", "华仔", "郭富城", "张学友")#注意 此时是元组
print("四大天王:%s, %s, %s, %s" % stars)
stars2 = ["黎明", "华仔", "郭富城", "张学友"] #注意 此时数据类型是列表
print("四大天王:%s, %s, %s, %s" % stars2)
#报错 TypeError: not enough arguments for format string
stars1 = ["黎明", "华仔", "郭富城", "张学友"]
print("四大天王:%s, %s, %s, %s" % (*stars1,))#此时(*stars1,)把原来的列表中的元素填充进了元组中
#stars3 = ["黎明", "华仔", "郭富城", "张学友"]
#print("四大天王:%s, %s, %s, %s" % (*stars3))#此时(*stars1,)
报错 虽说拆分后stars不止一个元素 但是定义元组时,括号内将stars3视作一个元素,
所以必须按照仅包含一个元素的定义方法定义元组
# SyntaxError: can't use starred expression here

更进一步:对元组进行部分拆包

#利用*实现部分数据打包

#*c表示位置个数 0个元素对应空列表

多个元素逐个放到列表

#利用*实现部分数据打包
#*c表示位置个数 0个元素对应空列表 多个元素逐个放到列表
tup1 = (1, 2, 3, 4, 5, 6)
a, *c, b = tup1
print(a, *c, b) #输出 1 2 3 4 5 6 多个元素输出的是列表 *c代表对列表进行拆包
print(a, c, b) #输出 1 [2, 3, 4, 5] 6

a,b,*c = tup1
print(a,b,c)#输出 1 2 [3, 4, 5, 6]

单个元素拆包示例
tup2 = (9,)
a, *c = tup2
print(a,c)#输出 9 [] 单个元素的列表拆包 若*后无元素 则输出一个空列表

元组嵌套时拆包示例
tup3 = (1, 2, (3, 4, 5), 6)
a, b, c, d = tup3
print(a,b,c,d)#输出 1 2 (3, 4, 5) 6
print(a,b,*c,d)#输出 1 2 3 4 5 6
a,b,*c = tup3
print(a,b,c)#输出 1 2 [(3, 4, 5), 6]
print(a,b,*c)#输出 1 2 (3, 4, 5) 6


字符串拆包


#拆包规则与元组拆包相同

#字符串拆包会将字符串每个字母拆分单独作为字符 包括特殊符号

#字符串拆包
#拆包规则与元组拆包相同
#字符串拆包会将字符串每个字母拆分单独作为字符 包括特殊符号
s = 'hello'
s1 = "he'll'o"
print(*s)#输出 h e l l o
a,*b = s
print(a,b)#输出 h ['e', 'l', 'l', 'o']
a,*b = s1
print(a,b)#输出 h ['e', "'", 'l', 'l', "'", 'o']
单引号被当作特殊字符 拆分后单独输出

列表拆包

#列表拆包

#规则与元组拆包相同

#列表拆包
#规则与元组拆包相同
L = ['aa',6,'hello','good','happy','lucky']
L1 = ['aa',6,'hello',('good','happy'),'lucky']
x,y,*z = ['aa',6,'hello','good','happy','lucky']
print(x,y,z)
#输出 x='aa' y=6 z=['hello','good','happy','lucky']
print(*L)#输出 aa 6 hello good happy lucky
x,y,*z = L1
print(x,y,z)#输出  aa 6 ['hello', ('good', 'happy'), 'lucky']

字典拆包

#字典拆包

#用法与元组和列表一样,但是字典拆包得到值是key

#字典拆包
#用法与元组和列表一样,但是字典拆包得到值是key
dick = {"张三":18, "李四":22, "王五":24,'李六':36}
a, b, *c = dick#输出 张三 李四 ['王五', '李六']
print(a,b,c)
#如果对字典拆包想要得到values 需要如此定义
a, b, c, d = dick.values()
print(a,b,c,d)



版权声明:本文为weixin_44494803原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。