通过名称引用对象作为属性

时间:2019-01-26 06:37:53

标签: python oop attributes coding-style

是否有充分的理由将对象列表存储为“子属性”?在下面的示例中,我在animals属性(例如例如 zoo.animals.<animal object referenced by name>)下的Zoo中存储了几个动物对象。这种语法使访问存储的动物的属性更加容易,我想知道是否还没有考虑到这种构造的缺点:

class Animal(object):
    def __init__(self, name, num_legs, furry):
        self.name = name
        self.num_legs = num_legs
        self.furry = furry

class ObjAsAttributes(object):
    def __init__(self, **kwargs):
        for k,v in kwargs.items():
            setattr(self, k, v)

class Zoo(object):
    def __init__(self, animals):
        self.name = 'my zoo'
        self.hours = '8am-6pm'
        animals = {animal.name:animal for animal in animals}
        self.animals = ObjAsAttributes(**animals)




animal_list = [Animal(name='bird', num_legs=2, furry=False),
               Animal(name='giraffe', num_legs=4, furry=True),
               Animal(name='octopus', num_legs=8, furry=False)]

zoo = Zoo(animal_list)
zoo.animals.bird.num_legs
# returns 2

1 个答案:

答案 0 :(得分:2)

我认为,这样做会使您的代码难以调试,不灵活且不可读。这是个坏主意。例如,会发生什么情况:

  1. 您的动物名包含空格吗?例如“电鳗”?
  2. 如果要遍历动物,则必须做
    for name in vars(obj):
        print(getattr(obj, name))
    
    • 本质上,您可能必须重新实现所有标准容器功能,例如插入,添加,删除,过滤器等,或者使用非常不直观的语法。
  3. 您如何将其与其他动物园合并或过滤?此外,如果需要,也无法对这些值进行排序。

属性旨在“保留”建模对象的数据或“描述特征”。您仅应将它们用于此目的。


主要是在寻求快速便捷的访问权限时,请使用dictOrderedDict

class Animal(object):
    def __init__(self, name, num_legs, furry):
        self.name = name
        self.num_legs = num_legs
        self.furry = furry

class Zoo(object):
    def __init__(self, animals):
        self.name = 'my zoo'
        self.hours = '8am-6pm'
        self.animals = {animal.name:animal for animal in animals}

animal_list = [Animal(name='bird', num_legs=2, furry=False),
               Animal(name='giraffe', num_legs=4, furry=True),
               Animal(name='octopus', num_legs=8, furry=False)]

zoo = Zoo(animal_list)
zoo.animals['bird'].num_legs
# returns 2