【问题标题】:Is it good to use setattr inside @classmethod decorator in Python在 Python 的 @classmethod 装饰器中使用 setattr 好不好
【发布时间】:2020-06-08 17:15:20
【问题描述】:

我编写了一个类,该类被多个具有不同输入参数的函数调用。

class demo:   
     def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar
     @classmethod
     def fromdict(cls, dict):
        for key, val in dict.values():
            setattr(cls, key, val)
        return cls(foo1, bar1)

有两种方法可以实例化类。在第一种方法中,我可以控制属性名称。而在第二种情况下,我事先不知道名字。在我们执行某些操作之前,有没有办法获取名称。或者有没有办法知道使用哪个方法来实例化类。

我知道在 classmethod 装饰器中它调用了类的原始 init

【问题讨论】:

  • 是否打算从字典中检索适当的值以传递给demo.__init__,类似于return cls(foo=dict['foo'], bar=dict['bar'])?目前尚不清楚您为什么要根据 dict 设置类属性,也不知道 foo1bar1 来自哪里。
  • 这意味着与两个固定属性和几个具有变量名称的变量属性一起使用。这意味着传递给类方法的任何字典必须至少具有 init 所需的两个属性。除了那个用户可以提供任意数量的键值对。但是,我可以进行一些操作,以便了解属性列表。对于这个要求,我想事先知道属性。
  • 您正在创建类属性而不是实例属性...这是故意的吗?
  • 查看列表并不意味着您必须创建类属性。关键是你的类必须有一些它期望 dict 包含的名称,在这种情况下,你可以像我的第一条评论一样简单地访问它们。您不能使用任意 dict 并期望找出哪些键指示用于 foobar 参数的值。
  • @chepner 感谢您的指导。它将帮助我解决问题。

标签: python python-3.x


【解决方案1】:

从提供的示例来看,您似乎没有任何理由需要在类范围内设置变量。如果该假设正确,简单的解决方案是直接设置字典项(并在 init 中使用可选的 kwargs)。

class demo:   
 def __init__(self, foo=None, bar=None):
    self.foo = foo
    self.bar = bar

 @classmethod
 def fromdict(cls, dct):
    # create instance
    obj = cls()
    # vars grants direct access to the underlying __dict__
    # so you can arbitrarily assign new variables
    return vars(obj).update(dct)

不过,这个问题并不完全清楚,所以请更具体地说明您想要实现的目标,我会更新。

小提示:避免使用dict 作为变量名,因为它是python 中的内置类型。调用 dict() 创建一个字典。

另外,在你的 for 循环中:

for key, val in dict.values()

你要的是for key, val in dct.items()

【讨论】:

    猜你喜欢
    • 2021-03-30
    • 2019-08-08
    • 2011-02-06
    • 2016-03-17
    • 2012-07-30
    • 2021-08-13
    • 2016-01-13
    • 2016-05-19
    • 2022-01-21
    相关资源
    最近更新 更多