2011-11-26 56 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等)之間的程序員角度來看沒有技術上的區別