【问题标题】:Python: Using a dummy class to pass variable names?Python:使用虚拟类传递变量名?
【发布时间】:2012-03-24 02:45:13
【问题描述】:

这是function that returns a dict whose keys are the names of the input arguments 的后续,我学到了很多东西(释义):

  • 总的来说,Python 对象不知道它们的名称。
  • 不,这通常对*args 是不可能的。您必须使用关键字参数
  • 当参数数量固定时,您可以使用locals 执行此操作
  • 使用全局变量()。这仅在模块范围内的值是唯一的情况下才有效,因此它很脆弱
  • 您最好还是不要这样做,而是重新考虑问题。

第一点强调了我对 Python 变量的根本误解。回答非常具有教学性,几乎是即时的,显然这是一个易于理解但容易混淆的话题。

由于我想学习如何正确地做事,创建一个虚拟类来简单地保存带有附加名称的变量是否被认为是不好的做法?

class system: pass
S = system ()
S.T = 1.0
S.N = 20
S.L = 10

print vars(S)

这实现了我的初衷,但我想知道是否有什么我没有考虑到的东西会在以后咬我。

【问题讨论】:

  • 我仍然不明白你的实际目标是什么。 “具有名称的值”的 Python 数据结构是一个字典:dict(T=1.0, N=20, L=10)。在某些情况下,有些人更喜欢您使用的命名空间对象,但如果没有更多上下文,很难给出建议。
  • 我错过了什么吗?这给了你什么字典没有的东西?
  • @PaoloBergantino:例如,argparse 使用这样的命名空间对象,因为有时通过S.T 访问属性比更嘈杂的S["T"] 更方便。

标签: python class dictionary


【解决方案1】:

我这样做是为了向 Javascript 致敬,在 Javascript 中,字典和实例变量之间没有任何区别。我认为它不一定是反模式,也因为与字典不同,如果你没有值,它会引发 AttributeError 而不是 KeyError,并且更容易发现名称的拼写错误。正如我所说,不是反模式,前提是

  1. 类的范围仅限于非常具体的用途
  2. 您正在调用的例程或方法(例如,您的示例中的 vars)本质上是私有的。我不想要具有该调用语义的公共接口,也不希望它作为返回的实体
  3. “虚拟”类的名称在其意图和它所代表的聚合类型上非常清楚。
  4. 该对象的生命周期很短且平安无事。这只是一个临时数据包。

如果不遵守这些约束,请选择具有属性的完全可识别的类。

【讨论】:

    【解决方案2】:

    你可以这样做,但为什么不使用字典呢?

    但如果你这样做,你最好将关键字 args 传递给类的构造函数,然后让构造函数将它们复制到应用程序的成员。类似:

    class Foo(object):
    
        def __init__(self, **kwargs):
            self.__dict__.update(kwargs)
    

    【讨论】:

    • 你也可以不抄袭:self.__dict__ = kwargs.
    • 这是否需要您在构建时知道所有输入参数?与添加 S.x 的成员相比,这有什么好处?
    • @SvenMarnach 是的,但是你不能像自定义 __repr__ 那样向类添加任何方法@
    • @Hooked 它只是更少的代码行和更少的代码编写。如果你愿意,你可以两者都做。
    • @SvenMarnach 你是对的,它不会覆盖它,除非你传递一个名为 __repr__ 的参数 :) 我的错
    猜你喜欢
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2015-06-09
    • 1970-01-01
    • 2021-11-30
    • 2018-03-31
    相关资源
    最近更新 更多