【问题标题】:Simplifying Init Method Python简化初始化方法 Python
【发布时间】:2021-11-21 20:38:27
【问题描述】:

有更好的方法吗?

def __init__(self,**kwargs):
        self.ServiceNo = kwargs["ServiceNo"]
        self.Operator = kwargs["Operator"]
        self.NextBus = kwargs["NextBus"]
        self.NextBus2 = kwargs["NextBus2"]
        self.NextBus3 = kwargs["NextBus3"]

属性(ServiceNo,Operator,...)始终存在

【问题讨论】:

标签: python-3.x class oop


【解决方案1】:

这取决于您所说的“更简单”。

比如,是不是你写的比我写的简单,即

def __init__(self,ServiceNo, Operator, NextBus, NextBus2, NextBus3):
    self.ServiceNo = ServiceNo
    self.Operator = Operator
    self.NextBus = NextBus
    self.NextBus2 = NextBus2
    self.NextBus3 = NextBus3

没错,我已经将每个属性名称重复了一次,但我已经更清楚地说明了__init__ 的哪些参数合法。调用者不能随意添加他们喜欢的任何其他关键字参数,只能看到它被默默地忽略。

当然,这里有很多样板;这是数据类可以解决的问题:

from dataclasses import dataclass


@dataclass
class Foo:
    ServiceNo: int
    Operator: str
    NextBus: Bus
    NextBus2: Bus
    NextBus3: Bus

(根据需要调整类型。)

现在每个属性都被提及一次,你就可以免费获得上面显示的__init__ 方法了。

【讨论】:

  • 次要注意:如果您希望强制通过关键字接收参数以避免前向兼容性要求以维持秩序(OP 仅以**kwargs 接收的可能原因),仍然可以使用单独命名的参数,您只需将 __init__def 更改为:def __init__(self, *, ServiceNo, Operator, NextBus, NextBus2, NextBus3):(没有名称的 * 会阻止按位置接收其右侧的参数)。
  • 我想我没有提到这一点,因为我知道我会马上介绍数据类,然后你会回到接受位置参数的问题。我不认为有任何方法可以让数据类生成需要仅关键字参数的__init__,但这会很好。
【解决方案2】:

如何更好?您并没有真正描述您要解决的问题。

如果是错误处理,可以在key不存在的情况下使用字典.get()方法。

如果您只是想要一种更简洁的初始化变量的方法,您可以删除 ** 并将字典本身作为变量,然后在代码的其他地方使用它,但这取决于您的其他方法在做什么。

【讨论】:

    【解决方案3】:

    由于属性和参数名称完全匹配,因此可用的 hacky 解决方案是直接从 kwargs dict 复制到实例的 dict,然后检查您是否获得了您期望的所有密钥,例如:

    def __init__(self,**kwargs):
        vars(self).update(kwargs)
        if vars(self).keys() != {"ServiceNo", "Operator", "NextBus", "NextBus2", "NextBus3"}:
            raise TypeError(f"{type(self).__name__} missing required arguments")
    

    我不推荐这个; chepner's options 都优于这种hackery,并且它们更可靠(例如,如果您使用__slots__ 来防止属性的自动激活,此解决方案将失败,因为实例将没有支持dict 你可以用vars拉)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 2015-05-17
      • 1970-01-01
      相关资源
      最近更新 更多