2011-07-13 33 views
30

我想導入一些包,這取決於用戶選擇的值。

默認爲file1.py

from files import file1 

如果用戶選擇file2,它應該是:

from files import file2 

在PHP中,我使用variable variables可以這樣做:

$file_name = 'file1'; 
include($$file_name); 
$file_name = 'file2'; 
include($$file_name); 

如何在Python中執行此操作?

+1

不要這樣做!使用輸入通常不值得信賴,盲目評估基於它的代碼是一個壞主意。 –

+0

謝謝,我現在使用默認設置導入。 – skargor

回答

43

Python沒有一個功能,就是直接相當於PHP的「變量變量」。要獲得「變量變量」的值(或任何其他表達式的值),可以使用eval函數。

foo = "Hello World" 
print eval("foo") 

但是,這不能用於import語句。可以使用__import__函數使用變量導入。

package = "os" 
name = "path" 

imported = getattr(__import__(package, fromlist=[name]), name) 

相當於

from os import path as imported 
26

由於Fredrik Lundh states:

總之,這裏的這些語句和功能是如何工作的:

import X導入模塊X,並且會在當前名字空間的模塊 的參考。或者換句話說,你已經運行這個 語句之後,就可以使用X.name指模塊X.

from X import *定義的東西導入模塊X,並且會在 當前命名空間中定義的所有公共對象的引用通過該模塊(即 是,所有沒有以「_」開頭的名稱)。或者在 換句話說,在你運行這個語句之後,你可以簡單地使用一個簡單的名字來引用在模塊X中定義的東西。但是X本身並不是 定義的,所以X.name不起作用。如果名稱已經定義,則 將被新版本替換。如果X中的名稱更改爲指向其他某個對象的 ,則您的模塊將不會注意到。

from X import a, b, c導入模塊X,並在 中創建對給定對象的當前名稱空間的引用。或換句話說,您可以在您的程序中使用abc現在使用 。

最後,X = __import__(‘X’)作品一樣import X,區別 你1)通過模塊名作爲一個字符串,2)明確指定 它給一個變量在當前的命名空間。 。

而且通過這,你在intrested最後一個方法方式

簡單地寫(例如):

var = "datetime" 
module = __import__(var) 
+0

感謝您提供一個清晰的答案。 – DrBailey

4

這可能是一個非常糟糕的主意,讓用戶選擇要導入的內容。包可以在導入時執行代碼,因此您可以有效地允許用戶在系統上隨意執行代碼!安全得多做類似

if user_input == 'file1.py': 
    from files import file1 as file 
elif user_input == 'file2.py': 
    from files import file2 as file 
else: 
    file = None 
    print "Sorry, you can't import that file" 
33

舊線,但我需要的答案,所以別人可能還是...

有在Python做到這一點更清潔的方式2.7+:

import importlib 


my_module = importlib.import_module("package.path.%s" % module_name) 
+0

提示:根據[import to work](http://stackoverflow.com/a/1260813/673991),你需要一個'package.path .__ init __。py'。 –

2

mattjbray的回答立足自己:

from importlib import import_module 

# lookup in a set is in constant time 
safe_names = {"file1.py", "file2.py", "file3.py", ...} 

user_input = ... 

if user_input in safe_names: 
    file = import_module(user_input) 
else: 
    print("Nope, not doing this.") 

保存的幾行代碼,並允許例如,以編程方式設置safe_names,或者加載多個模塊並將它們分配給字典。