1.类的__repr__ 方法
? 自定义类实例化之后,如果需要输出实例的信息,可在__repr__ 中定义字符串信息。
(1)默认的输出
class User:
def __init__(self):
self.name = "User"
if __name__ == '__main__':
user = User()
print(user)
[out] <__main__.User object at 0x00000206C7E29760>
? (2)自定义实例输出
class User:
def __init__(self):
self.name = "User"
def __repr__(self):
return f"I'am {self.name}."
[out] I'am User.
2.对象的克隆
? (1)一个十分有趣的例子
l = [1, 2, 3]
l2 = l
l3 = l[:]
l[0] = 'X'
print(l2)
print(l3)
? 查看输出
['X', 2, 3]
[1, 2, 3]
? 可以看到,l 改变之后,l2 会随着l 改变,而l3 则不会。
? 这是因为l2 是跟l 共享内存空间的,即l2 浅复制了l –内容会随着l 的改变而改变;l3 深复制了l –l3 占据一个独立的内存空间,不随着l 的改变而改变(可以类比C++的拷贝函数)。
? (2)制作浅副本 将容器的变量名直接赋值。
class User:
def __init__(self):
self.name = 'User'
self.data = 1
def __repr__(self):
return f"User(name: {self.name}, data: {self.data})"
if __name__ == '__main__':
user = User()
newuser = user // 用容器名赋值。
user.data = 2
print(newuser)
[out] User(name: User, data: 2)
(3)制作深副本
? 使用标准库中的copy.copy
form copy import copy
class User:
def __init__(self):
self.name = 'User'
self.data = 1
def __repr__(self):
return f"User(name: {self.name}, data: {self.data})"
if __name__ == '__main__':
user = User()
newuser = copy(user) // copy函数
user.data = 2
print(newuser)
[out] User(name: User, data: 1)
3.is 与==
? == : 两个变量的值相同为True
? is : 两个变量在内存中表示同一位置的值。
? 可以用上面列表的克隆为例
if __name__ == '__main__':
l = [1, 2, 3]
l2 = l
l3 = l[:]
print(f"l2 == l: {l2==l}, l3 == l: {l3==l}")
print(f"l2 is l: {l2 is l}, l3 is l: {l3 is l}")
l2 == l: True, l3 == l: True
l2 is l: True, l3 is l: False
4.有趣的*args 和**kwargs
? Python的*args 和**kwargs是 其能够实现可变参数。
? *args : 充当可变长度的数组参数,将传入的"没有归属"参数,即没指定变量名的参数,注入一个元组中。
? **kwargs : 充当可变长度的字典参数。
def paramsTest(required, *args, **kwargs):
print(f"params: {required}, {args}, {kwargs}")
if required:
print(required)
for arg in args:
print(arg)
if kwargs:
print(kwargs)
if __name__ == '__main__':
paramsTest(1, 2, 3, 4, x=5, y=6, z=7)
[out]:
params: 1, (2, 3, 4), {'x': 5, 'y': 6, 'z': 7}
1
2
3
4
{'x': 5, 'y': 6, 'z': 7}
5.* 和** 的神秘功能
? * 和** 操作符有一个比较引用和有点神秘的功能–用于参数的解包。
? 参考例子
def paramsTest(x, y, z):
print(f"x = {x}, y = {y}, z = {z}")
if __name__ == '__main__':
l = [1, 2, 3]
d = {'x': 1, 'z': 3, 'y': 2}
print(*l) // argument after * must be an iterable, not User
paramsTest(**d)
1 2 3
x = 1, y = 2, z = 3
* : 将容器中的值解包,容器必须是可迭代的。
** : 将容器中的值以键值对的形式展开,容器必须是mapping 类型的。
? print(*l) // argument after * must be an iterable, not User paramsTest(**d)
1 2 3 x = 1, y = 2, z = 3
`*`: 将容器中的值解包,容器必须是可迭代的。
`**`: 将容器中的值以键值对的形式展开,容器必须是`mapping`类型的。
?
|