[英]Casting in defining attributes of a Class?
I'm a Python newbie and I'm dealing with Object Programming. 我是Python新手,正在处理对象编程。 Studying my teacher code, I've found something strange at self.items = list(items)
. 通过研究我的老师代码,我发现self.items = list(items)
有点奇怪。 Look at the overall code: 看一下整体代码:
class Truck():
'''
This class models a truck
'''
def __init__(self, plate_number, capacity, items):
'''
Constructor of an object of class Truck
:param plate_number: a unique number Identifying the truck
:param capacity: maximum weight that the truck can carry
:param items: list of objects of class Item carried by the truck
'''
self.plate_number = plate_number
self.capacity = capacity
self.items = list(items)
So, why should I cast the parameter items
, whereas the other parameters don't need this operation? 那么,为什么我应该强制转换参数items
,而其他参数则不需要此操作呢?
The other parameters ( plate_number
and capacity
) are probably immutable (a string and an int presumably). 其它参数( plate_number
和capacity
)可能是不可变的(字符串和一个int大概)。 However items
is a list (if we are to trust the docstring) which is mutable. 但是items
是一个可变的列表(如果我们要信任文档字符串)。
Using it as it is in Truck
's __init__
would have resulted in changes made to truck_obj.items
affecting the original passed items
list as well (and vice-versa). 按原样在Truck
的__init__
使用它会导致对truck_obj.items
更改也影响原始传递的items
列表(反之亦然)。
Calling list(items)
results in a newly created list being assigned to self.items
. 调用list(items)
导致将一个新创建的列表分配给self.items
。 This can also be achieved by using slicing syntax: self.items = items[:]
. 这也可以通过使用切片语法来实现: self.items = items[:]
。
Compare: 相比:
class A:
def __init__(self, items):
self.items = items
li = [1, 2]
obj = A(li)
li[0] = 9
print(obj.items)
# [9, 2] oops! we modified obj.items without intending to
to 至
class A:
def __init__(self, items):
self.items = list(items) # or items[:]
li = [1, 2]
obj = A(li)
li[0] = 9
print(obj.items)
# [1, 2]
Your instructor is saying "I can only work with items
in the class, if they're in a list
". 您的老师说:“如果list
有items
,我只能使用该items
”。 What this roughly translates to is, "The items
attribute of class Truck
must be an ordered, indexed, and mutable collection". 大致的翻译是,“ Truck
类的items
属性必须是有序,可索引且可变的集合”。
For example, there is a chance that someone passes in a tuple
for items
, and if for example, you needed to add or remove items in the Truck
class, you can't add or remove items from a tuple
(but you can with a list
). 例如,某人可能会传入一个tuple
来存储items
,例如,如果您需要在Truck
类中添加或删除项目,则不能在tuple
添加或删除项目(但是可以list
)。
Casting to a list
is explicit, and should it not raise an error, is guaranteed to be a list regardless of what gets passed into items
. 铸造一个list
是明确的,而应该把它不会引发错误,是保证无论什么被传递到列表中items
。 This is a part of what we call "pythonic". 这是我们所谓的“ pythonic”的一部分。
EDIT: To piggy back off of a very good point by DeepSpace, casting to list
also creates a shallow copy of the list to manipulate, as opposed to the list itself. 编辑:为了通过DeepSpace收回一个很好的点,强制转换为list
还会创建要操作的列表的浅表副本,而不是列表本身。
In this example your teacher is assuming that plate_number
and capacity
are two immutable variables and items
should be represented as a list
. 在这个例子中你的老师是假设plate_number
和capacity
是两个不变的变量, items
应该被表示为一个list
。
So, when passing variables in __init__()
method your items
variables must be an iterable
and can be represented as a list
. 因此,当在__init__()
方法中传递变量时,您的items
变量必须是iterable
并且可以表示为list
。
You can see this example with a generator
: 您可以使用generator
查看此示例:
class Truck():
def __init__(self, plate_number, capacity, items):
self.plate_number = plate_number
self.capacity = capacity
self.items = list(items)
def __repr__(self):
return "plate_number: %r\ncapacity: %r\nitems: %r" % (self.plate_number, self.capacity, self.items)
# Test
if __name__ == '__main__':
number = 12
capacity = 13
# Generator wich can be represented as a list
items = (k for k in [1,2,3,4])
app = Truck(number, capacity, items)
print(app)
# OR
#print(repr(app))
Output: 输出:
plate_number: 12
capacity: 13
items: [1, 2, 3, 4]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.