如何在Python中动态组合和访问类属性?

2024-06-28 10:58:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python类,它的属性名为:date1、date2、date3等

在运行时,我有一个变量I,它是一个整数。

我要做的是根据I的值在运行时访问适当的date属性

例如

如果i==1,我想访问myobject.date1

如果i==2,我想访问myobject.date2

我想对类而不是属性做一些类似的事情。

例如,我有一堆类:MyClass1、MyClass2、MyClass3等等,还有一个变量k

如果k==1,我想实例化MyClass1的一个新实例

如果k==2,我想实例化MyClass2的一个新实例

我该怎么做?

编辑

我希望避免使用一个巨大的if-then-else语句来选择适当的属性/类。

Python中有没有一种方法可以使用变量的值动态地组合类名?


Tags: 实例编辑dateif属性整数事情then
3条回答

如果在运行时才知道属性的名称,则可以使用getattr()访问该属性:

obj = myobject()
i = 7
date7 = getattr(obj, 'date%d' % i) # same as obj.date7

如果将编号类保存在名为foo的模块中,则可以再次使用getattr()按编号访问它们。

foo.py:
  class Class1: pass
  class Class2: pass
  [ etc ]


bar.py:
  import foo
  i = 3
  someClass = getattr(foo, "Class%d" % i) # Same as someClass = foo.Class3
  obj = someClass() # someClass is a pointer to foo.Class3
  # short version:
  obj = getattr(foo, "Class%d" % i)()

尽管如此,您确实应该避免这样的事情,因为您永远无法找到这些编号的属性和类的使用位置,除非通过读取整个代码库。你最好把所有的东西都放进字典里。

好吧,好吧。。。看来这需要一点工作。首先,对于你的约会对象,它们可能应该存储为属性的字典。例如,myobj.dates[1],等等。

对于类来说,听起来你想要多态性。所有MyClass*类都应该有一个共同的祖先。祖先的__new__方法应该找出要实例化的子级。

父母知道该做什么的一种方法是对孩子们的口述。父类不需要通过搜索其所有子类来枚举其子类,但实现起来要复杂一些。请参阅here以获取有关如何采用该方法的更多信息。特别是阅读评论,他们会对其进行扩展。

class Parent(object):
    _children = {
      1: MyClass1,
      2: MyClass2,
    }

    def __new__(k):
        return object.__new__(Parent._children[k])

class MyClass1(Parent):
    def __init__(self):
        self.foo = 1

class MyClass2(Parent):
    def __init__(self):
        self.foo = 2

bar = Parent(1)
print bar.foo # 1
baz = Parent(2)
print bar.foo # 2

第三,你真的应该重新考虑你的变量命名。不要用数字来枚举变量,而要给它们取有意义的名字。ik不适合使用,因为按照惯例,它们是为循环索引保留的。

现有代码的一个示例将非常有助于改进它。

对于第一种情况,您应该能够:

getattr(myobject, 'date%s' % i)

对于第二种情况,您可以执行以下操作:

myobject = locals()['MyClass%s' % k]()

然而,事实上,你首先需要这样做,这可能是一个迹象,表明你正在以一种非常非Python的方式解决这个问题。

相关问题 更多 >