2011-11-26 52 views
3

Supose我有这样的变量:var1,var2,var3,var4,var 5,...,var100(列表和词典不适合我的情况,因为所有这些变量都是类对象)。Python:如何使用变量作为字符串?

我必须处理所有这些类似的方式,例如:

if var1: 
    print 'var1 is not None' 
if var2: 
    print 'var2 is not None' 
if var3: 
    print 'var3 is not None' 
... 
if var100: 
    print 'var100 is not None' 

以这样的方式,我会写的代码200个数百行...

但也许有一些方法来处理所有他们在for声明中,如:

for i in range(1,101): 
    if var%s % i: #I know this is not right, but idea is understood 
     print 'var%s is not None' % i 

所以我只写了3行代码。

它可能在Python中做什么?

谢谢!

+2

我不相信“列表和字典在你的情况下不适合”。你为什么这么认为? –

+1

“列表和字典不适合我的情况” - 除非它是一个不明确的任务要求(在这种情况下,如果有人提出了这个要求),绝对没有理由这样做。 – delnan

+0

我的var1,var2,...是类对象。 –

回答

8

locals()返回局部变量的字典。同样,globals()返回全局变量的字典。您可以在其中一个中找到变量及其值,具体取决于定义的位置。

for i in range(1,101): 
    if ('var%s' % i) in locals(): 
     print 'var%s is not None' % i 
     print locals()['var%s' % i] 
+0

它被定义为类属性 –

2

您可以修改类的动态属性:

class A(object): 
    pass 
for i in range(100): 
    setattr(A, "var%i" % i, i) 

创建了100个属性叫A.var0A.var99类。这种方法有两个问题:

  1. 这些属性访问相当不方便。 (这是可能的getattr(),但有他们在一个列表会使循环访问他们就轻松多了。)

  2. 如果类A有一个自定义元类,目前还不清楚如何与动态创建的属性,这些属性的元类交易。

从Django的源代码,看一眼,我可以看到django.db.models.Model确实有一个自定义元类,而事实上所有属性必须已在类的创建时间来定义,因此上述方法将无法正常工作。实际创建类之前,您必须创建完整的类字典。以下是一种方法:

model_dict = {} 
for i in range(100): 
    model_dict["var%i" % i] = models.CharField(max_length=10) 
model_dict["var_list"] = model_dict.values() 
MyModel = type("MyModel", (models.Model,), model_dict) 

这使用three-parameter form of type()来动态创建一个类型。这部分解决问题2.

为了解决问题1,上面的代码公开还向该类中添加了一个属性,允许以列表形式访问所有models.CharField实例,而不是按名称访问。

+0

你能发布一个链接到官方文档描述这种方法吗? –

+0

@VitaliPonomar:我给你链接到'type()'的文档。还有什么你需要更多的信息? –

+0

也许您有兴趣[此SO回答](http://stackoverflow.com/q/6581949/279627)。 –

5

我希望你没有把你的实际需求埋在第十个评论下面的主要问题。实际上,看起来你想要的是动态获取类的属性 - 在这个例子中是Django模型中的一个字段。这很简单:你只是这样做:

getattr(instance, varname) 
+0

getattr(user_obj,'var1') - 这么简单? –

2

我认为你正在寻找eval命令。

希望这有助于

问候,Maecky

+0

'eval'很少是一个好的解决方案。哦,还有一个单挑,它往往会在stackoverflow上吸引downvotes。 –

+0

好吧,这对打印方法很好。但是,如果我想动态地重新定义它,在这种情况下如何使用eval():对于范围(1,101)中的我:eval('var%s'%i)= str(i)+ a –

+2

'eval在这种情况下是非常糟糕的解决方案。 –

1

夫妇不同的方式来做到这一点,你可以下载从全局或当地人的变量字典,像这样: globals()['var1']

import __main__和使用getattr(__main__,'var1')

将这些内容放入for循环中,将变量名称分配给字符串并返回,例如

如果该类存在于您的测试,使用try except

import __main__ 

for i in range(1,101): 
    try: 
    func = getattr(__main__,'var%s' % i) 
    if func is not None: 
     print 'var%s is not None' % i 
    except: 
    print 'var%s does not exist' 

如果它埋在一个类中使用的类名,而不是__main__。如果类名是var%s,则在上面的循环中使用func上的getattr,以便抓取每个类中需要的内容。

1

我认为列表或字典实际上是解决问题的最合适的方法。在Python中,数据结构可以包含其他对象。这包括您自己创建的对象,因为从您定义的类型(类)和Python本机类​​型(字符串,int等)之间的程序员角度来看没有技术上的区别