在定义类的属性时进行转换?

时间:2017-03-10 17:29:38

标签: python class attributes

我是一个Python新手,我正在处理对象编程。 研究我的老师代码,我在self.items = list(items)找到了一些奇怪的东西。 看一下整体代码:

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)

那么,我为什么要转换参数items,而其他参数不需要这个操作?

3 个答案:

答案 0 :(得分:4)

其他参数(plate_numbercapacity)可能是不可变的(大概是字符串和int)。但是items是一个可变的列表(如果我们要信任docstring)。

Truck的{​​{1}}中使用它会导致对__init__的更改也会影响原始传递的truck_obj.items列表(反之亦然) )。

调用items会将新创建的列表分配给list(items)。这也可以通过使用切片语法来实现:self.items

比较

self.items = items[:]

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

答案 1 :(得分:0)

您的导师说:“我只能在班级items工作,如果他们在list”。这大致转换为“类items的{​​{1}}属性必须是有序的,索引的和可变的集合”。

例如,某人可能会Truck传递tuple,例如,您需要在items课程中添加或删除项目,不添加或删除Truck中的项目(但您可以使用tuple)。

转换为list是明确的,如果不引发错误,则无论传递到list的内容是什么,都保证是一个列表。这是我们所谓的“pythonic”的一部分。

编辑:要深入了解DeepSpace的一个非常好的观点,强制转换为items也会创建一个要操作的列表的浅表副本,而不是列表本身。

答案 2 :(得分:0)

在此示例中,您的教师假设plate_numbercapacity是两个不可变变量,而items应表示为list

因此,在__init__()方法中传递变量时,items变量必须为iterable,并且可以表示为list

您可以使用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))

输出:

plate_number: 12
capacity: 13
items: [1, 2, 3, 4]
相关问题