1 *args 打包参数
*args由两部分构成为——*和args,这里的重点是*,*的作用,有2个—— 打包参数(pack)和拆分参数(unpack)
例1:
def foo(*number):
print(number)
foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
(注:紫色字体为运行结果,下同)
给函数5个参数,成功运行了,而且输出是参数构成的元组。如果number前不加∗号,那么很明显foo()只能接受1个参数,参数给多了少了都要报错。而加上∗,就能成功运行。原理:∗把函数foo()接受到的多个参数1,2,3,4,5,打包成了元组(1,2,3,4,5),赋值给了形参number.
例2:
def foo(*number):
for i in number:
print(i)
print(type(number))
foo(1, 2, 3, 4, 5)
1
2
3
4
5
<class 'tuple'>
从例2可以看出,number确实被赋予了(1,2,3,4,5)这个实参。
例3:
def foo(a, *number):
print('a:', a)
print('number:', number)
for i in number:
print(i)
print(type(number))
foo(1, 2, 3, 4, 5)
a: 1
number (2, 3, 4, 5)
2
3
4
5
<class 'tuple'>
从例3可以看出,number接受到的实参变成了(2,3,4,5),第一个参数1被形参a接受走了。
所以这里我们可以给出∗作用的完整版:函数接受实参时,按顺序分配给函数形参,如果遇到带∗的形参,那么就把还未分配出去的实参以元组形式打包(pack),分配给那个带∗的形参。
例5:
def foo(a, b, *number, c):
print('a:', a)
print('b:', b)
print('c:', c)
print('number:', number)
for i in number:
print(i)
print(type(number))
foo(1, 2, 3, 4, 5)
Traceback (most recent call last):
File "C:/Users/PycharmProjects/untitled10/test19.py", line 11, in <module>
foo(1, 2, 3, 4, 5)
TypeError: foo() missing 1 required keyword-only argument: 'c'
注意例5我特地找了个报错的例子。c前面的参数带*,把剩下的实参都接受走了,c没有传入实参!
到这里,∗的打包(pack)就解释清楚了。
还留一个小尾巴:args是啥?
答案是:args仅仅是一个约定俗成的形参的写法,你写成把别的也没事,但是不利于统一形式。就像我们的例子里,一直用的number,也照样运行正确。
2 * 拆分参数
例6:
def bar(a,b,c):
print(a,b,c)
bar(*[1,2,3])
1 2 3
可以看出,∗ *∗这次没有用在函数定义中,而是用在了函数调用中。在本例中的作用是啥呢?
答案是:把打包了的实参(元组或列表),拆分(unpack)成单个的,依次赋值给函数的形参。
在本例中,打包了的实参[1,2,3]被拆分,1赋值给了形参a,2赋值给了形参b,3复制给了形参c.
3 **kwargs 打包参数
上边*args学懂了**kwargs也就很容易明白了。
**kwargs也有两部分构成为——**和kwargs。这里的重点是∗ ∗。kwargs仅仅是一个约定俗成的形参写法,没有其他特殊含义,换成其他的也照用不误,但是为了代码可读性,最好还是用约定俗成的。
∗ ∗的作用同样也有两个—— 打包参数(pack)和拆分参数(unpack)!
但是区别还是有的,简单来说就是:
打包(pack):*args是把多个位置参数打包成元组,**kwargs是把多个关键字参数打包成字典。
拆分(unpack):*args是把打包了的参数拆成单个的,依次赋值给函数的形参,**kwargs是把字典的键值拆成单个的,依次赋值给函数的形参。
例10:
def bar(**number):
print(number)
bar(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
例11
def bar(a, b, c):
print(a,b,c)
bar(**{'a': 1, 'b': 2, 'c': 3})
1 2 3
注意这里有个需要注意的地方,就是用∗ ∗方式拆解字典给形参赋值时,需要字典的键名和函数形参一直,否则会报错。
————————————————
以上为引用加个人修改
原文链接:https://blog.csdn.net/lllxxq141592654/article/details/81288741
4 继承父类实例
# 【【【-----test4 继承父类,增加子类属性-----】】】
class A():
def __init__(self,name,color):
self.name=name
self.color=color
pass
def __str__(self):
return '调用A'
pass
class B(A):
def __str__(self):
return '%s的颜色是%s'%(self.name,self.color)
pass
pass
peter=B('peter','white')
print(peter)
bob=A('Bob','black')
print(bob)
运行结果:
peter的颜色是white
调用A
# 【【【-----test5 super()调用父类-----】】】
class Car(object):
def __init__(self,owner,year,brand):
self.owner=owner
self.year=year
self.brand=brand
pass
# def __str__(self):
# '''
# 打印车辆信息
# :return:
# '''
# return 'The owner of the %s is %s,and the car is produced in %s'%(self.brand,self.owner,self.year)
# pass
def get_info(self):
'''
打印车辆信息
:return:
'''
print('The owner of the %s is %s,and the car is produced in %s'%(self.brand,self.owner,self.year))
pass
ferrari=Car('Celia','2022','Ferrari')
ferrari.get_info()
class ElecticalCar(Car):
def __init__(self,battery,*wargs):
'''
:param battery:
:param wargs: *wargs表示打包参数,表示将接收到的信息依次分配给super()中的形参
'''
super().__init__(*wargs) #直接调用父类的属性
self.battery=battery # 增加子类(电车类)的专有信息,电量
pass
def get_battery(self):
'''
打印电池信息
:return:
'''
print('The battery of the car is {}'.format(self.battery))
pass
pass
tesla=ElecticalCar('100000kwh','Celia','2021','Tesla')
tesla.get_info()
tesla.get_battery()
运行结果: The owner of the Ferrari is Celia,and the car is produced in 2022 The owner of the Tesla is Celia,and the car is produced in 2021 The battery of the car is 100000kwh 说明顺利继承父类的__init__()属性和get_info()方法