我有一个Python类,其属性名为:date1,date2,date3等。
在运行时,我有一个变量i,它是一个整数。
我想要做的是根据i的值在运行时访问相应的日期属性。
例如,
如果i == 1,我想访问myobject.date1
如果我= = 2,我想访问myobject.date2
我想为类而不是属性做类似的事情。
例如,我有一堆类:MyClass1,MyClass2,MyClass3等。我有一个变量k。
如果k == 1,我想实例化一个新的MyClass1实例
如果k == 2,我想实例化一个新的MyClass2实例
我该怎么做?
修改
我希望避免使用巨大的if-then-else语句来选择合适的属性/类。
Python中有没有办法使用变量的值动态编写类名?
答案 0 :(得分:25)
在运行时间之前,如果您不知道其名称,则可以使用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)()
说了这么多,你真的应该避免这种事情,因为除了阅读整个代码库之外,你永远无法找到这些编号属性和类的使用位置。你最好把所有东西放在字典里。
答案 1 :(得分:5)
对于第一种情况,您应该能够:
getattr(myobject, 'date%s' % i)
对于第二种情况,你可以这样做:
myobject = locals()['MyClass%s' % k]()
但是,您首先需要这样做的事实可能表明您正在以非Pythonic的方式解决问题。
答案 2 :(得分:4)
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
第三,你真的应该重新考虑你的变量命名。不要使用数字来枚举变量,而是给它们提供有意义的名称。 i
和k
很难使用,因为它们是按照惯例为循环索引保留的。
现有代码的示例将非常有助于改进它。
答案 3 :(得分:2)
我同意Daenyth的意见,但如果你感觉很挑剔,你可以使用所有课程附带的 dict 方法:
>>> class nullclass(object):
def nullmethod():
pass
>>> nullclass.__dict__.keys()
['__dict__', '__module__', '__weakref__', 'nullmethod', '__doc__']
>>> nullclass.__dict__["nullmethod"]
<function nullmethod at 0x013366A8>
答案 4 :(得分:1)
获取所有属性的列表,请尝试:
dir(<class instance>)
答案 5 :(得分:0)
对于第一个例子,我将在类上添加一个实例方法。
def get_date_for_i(self, i):
if i == 1:
return self.date1
elif i == 2:
return self.date2
# etc...
对于第二个我会使用工厂功能:
def get_class_for_k(k):
if k == 1:
return MyClass1
if k == 2:
return MyClass2
# etc...