【问题标题】:Avoid Redundancy in Python避免 Python 中的冗余
【发布时间】:2023-12-08 23:38:02
【问题描述】:

我最近开始为 Ubuntu Server 管理员使用 Python 2.6,但遇到了两个关于冗余的小问题:

首先是导入:它们看起来都像

从类中导入类

from class import Class

第二件事是__init__ 方法:

__init__(self,arg1,...,argn):
    self.arg1 = arg1
    ...
    self.argn = argn

有没有办法避免这些重复?

【问题讨论】:

    标签: python import init redundancy


    【解决方案1】:
    from module import Class
    

    类名与其包含的模块名不同是很常见的。如果每个模块只有一个具有相同名称的类,请考虑将该类在层次结构中上移一级。

    def __init__(self, a, b, c):
      self.a = a
      self.b = b
      self.c = c
    

    这确实看起来有点烦人,但与其他替代方案相比,它确实不错,可读性也不错。但是,如果您有很多参数只是分配为属性而在 init 中没有其他工作,那么请考虑从 namedtuple 或类似的继承,它可以为您生成这样的样板。 (特别是 Namedtuple 具有其他分支,并且仅在某些情况下适用。我将它用作可以处理此类样板的基类的示例。)

    【讨论】:

      【解决方案2】:

      第二件事不是冗余——它是设置实例属性。你也可以这样做:

      class Foo:
      
         def __init__(self, **kwargs):
             for name, value in kwargs.items():
                setattr(self, name, value)
      

      但是你需要像这样调用 Foo:

         Foo(arg1=1, arg2=2, arg3=3)
      

      您的导入似乎也有不正确的语法。应该是from Class import Class。这对您来说似乎是多余的,因为您似乎将每个类存储在一个单独的文件(模块)中 - 这完全是多余的。 Python 不是 Java,通常应该在一个模块中保存更多对象。请记住,该模块本身就是一个对象。此外,您应该正确命名模块 - 默认代码样式指南说模块应该全部小写,没有特殊字符。比如reurllib

      【讨论】:

      • 已经谢谢了!我更正了我的导入,并且从现在开始将模块保持小写。如何在不分割大型模块的情况下有效地处理/编辑大型模块?
      • 大模块是什么意思? 3k 行代码是一个大模块吗?这样的模块可以包含很多类。与Java/C++ 相比,您可以在 python 中编写更稀疏的代码,因此在模块中保留多个类并不意味着很大。
      【解决方案3】:

      args 的版本:

      class Foo:
      
         def __init__(self, *args):
             for index,arg in enumerate(args):
                setattr(self, 'arg%s'%index, arg)
      
      
      Foo(1,2,3)
      >>> Foo.arg0
      1
      

      【讨论】:

      • 我同意,这根本不是 Pythonic。显式比隐式好,这在我看来像是隐式魔法的一个温和案例。
      • 希望实际的属性名称不是 arg0 到 argN,因为如果是,它们应该是一个序列。如果不是,则此答案不适用。
      • 这可能很丑陋和不符合 Python 标准,但这也不是重构比赛,不是吗?并且代码回答了作者的问题字面意思
      • @Frost:仅当您从字面上将 OP 对“arg1”的使用解释为实际变量名而不是元语法变量时。如果它有“foo”和“bar”,那么问题仍然是一样的,但你的答案是错误的。
      • 而且,实际上,根据您的解释,您的答案是错误的:OP 以 arg1 开头,但您以 arg0 开头。
      最近更新 更多