【问题标题】:Extending a python list class to perform additional functions on its contents?扩展 python 列表类以对其内容执行附加功能?
【发布时间】:2012-02-18 23:06:11
【问题描述】:

我想创建一个对象来保存其他对象,并在它保存的每个对象上调用一个方法。最终目标是为程序生成脚本。每个对象都包含一个可以用printCommand() 打印的命令,最终打印到一个文件中。我原来的解决方案是这样的:

a = ObjectList()
a.appendObject(Object())
b = ObjectList()
b.appendObject(Object())

listOfObjects = [a, b]
for Object in listOfObjects:
    Object.printCommand()

我创建一个列表变量,将对象添加到 thw 列表,然后循环它发出命令。虽然这可行,但我主要是为了自学编程,所以我想知道是否有比编写代码来将项目追加、弹出等更优雅的解决方案。对象中的列表。由于list 已经包含这些功能,我认为正确的做法是扩展list

class Object:
    def __init__(self):
        self.Command = "Script Command"

    def printCommand(self):
        print(self.Command)

class ObjectList(list):
    def printCommand(self):
        for Object in self.LISTCONTENTS:
            Object.printCommand()

但是,我不知道如何告诉它迭代自己的内容。 self.LISTCONTENTS 属于什么? list 对象在哪里存储其内容,如何从方法中访问它们?

【问题讨论】:

    标签: python oop list python-3.x


    【解决方案1】:

    你可以遍历self:

    超类方法(即__iter__())都存在。在 for 语句的上下文中说 self 将导致调用适当的方法。

    class Object:
        def __init__(self):
            self.Command = "Script Command"
    
        def printCommand(self):
            print(self.Command)
    
    class ObjectList(list):
        def printCommand(self):
            for Object in self:
                Object.printCommand()
    
    lst = ObjectList()
    lst.append(Object())
    lst.append(Object())
    
    lst.printCommand()
    

    它的工作方式是list 实现__iter__,它在迭代对象时在后台调用:

    >>> for e in [1,2,3].__iter__():
    ...  print(e)
    ... 
    1
    2
    3
    >>> for e in [1,2,3]:
    ...  print(e)
    ... 
    1
    2
    3
    

    【讨论】:

      【解决方案2】:

      (a) 永远不要创建一个名为 Object 的类,它与 object 太接近了。

      (b) 绝对不需要从list 继承,坦率地说,我根本怀疑是否需要使用自己的类。

      (c) 对列表的每个元素调用函数的正常方法是使用map。如果需要重复映射同一个函数,可以使用partial将该函数绑定到map的第一个参数。

      现在去看看文档。

      【讨论】:

      • Re (c): map 不是为了副作用,列表推导也不是。只需使用 for 循环即可。
      • @delnan:没有理由不能将它用于副作用。如果它困扰您,选项包括生成器表达式,或编写您自己的非列表生成迭代器函数。无论如何,我的观点是这里根本不需要继承。
      • 当然可以,但这不是惯用的。 for 循环是正确的(如被广泛接受的)选择——不是 OP 提出的怪异,正如你所说的那样。
      • @delnan:for 循环是惯用的,但由于它不是一流的对象,因此例如不可重用。
      • 一个单独的循环,没有其他任何东西,多久需要成为一流的对象(赋值语句也不是一流的对象,但我敢说没有理智的人使用@987654330 @ 反而)?在极少数情况下它会派上用场,将它包装在一个函数中很容易。一个额外的不需要的(在这种情况下肯定是,即使你一般不同意)属性如何推翻一个成语?
      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多