2016-04-14 21 views
2

işlevinin yerel kapsamı içinde nasıl çalıştırabilirim. Ancak, her zaman küresel kapsamda değerlendirir.Python: eval() işlevini yerel olarak bir işlevin yerel kapsamındaki eval() işlevini kullanmaya çalıştığım

1- Bu kod çalışır:

var1 = 1 
var2 = 2 
var3 = 3  
myDict = dict((name, eval(name)) for name in ["var1", 
               "var2", 
               "var3"]) 
print(myDict["var1"]) 

2- 2.

def test2(): 
    lvar1 = 1 
    lvar2 = 2 
    lvar3 = 3 
    myDict = dict((name, eval(name), locals()) for name in ["lvar1", 
                  "lvar2", 
                  "lvar3"]) 
    print(myDict["lvar1"]) 
olarak lvar1

def test1(): 
    lvar1 = 1 
    lvar2 = 2 
    lvar3 = 3 
    myDict = dict((name, eval(name)) for name in ["lvar1", 
               "lvar2", 
               "lvar3"]) 
    print(myDict["lvar1"]) 

3- aynı sonuç için NameError Atar

Kendi örneklerine sahip

+4

Belki de daha önemli bir soru şudur: [gerçekten değerlendirmeye ihtiyacınız var mı?] (Https://stackoverflow.com/questions/1832940/is-using-eval-in-python-a-bad-practice) – Joost

+0

@cjahangir Bu bir ¯ \\ _ (ツ) _/¯ öneriydi – Adib

+0

@Adib, bilgisayarımda çalışıyor – cjahangir

cevap

2

Fonksiyonun yerel kapsamını döndürmek için locals() (veya vars()) aramasının sonucunu kaydedin. Aksi takdirde, jeneratör ifadesinin içinde locals() gen-expr'ın yerel kapsamını döndürür.

def test3(): 
    lvar1 = 1 
    lvar2 = 2 
    lvar3 = 3 
    scope = locals() 
    myDict = dict((name, eval(name, scope)) for name in [ 
        "lvar1", "lvar2", "lvar3"]) 
    print(myDict["lvar1"]) 

BTW, sözlük oluşturma gerekli değildir: read this için önemli olduğunu tüm

myDict = locals() # or vars() 
4

İlk: ifade argüman ayrıştırılır ve teknik olarak (bir Python ifadesi olarak değerlendirilir

küresel ve yerel ad alanı olarak globals ve locals sözlükleri kullanarak konuşma, bir koşul listesi. Eğer globals sözlüğü mevcutsa ve ‘__builtins__’ eksikse, ifade ayrıştırılmadan önce mevcut globals globals'a kopyalanır. Bu, ifadesinin normal olarak standart __builtin__ modülüne tam erişime sahip olduğu ve sınırlı ortamların yayıldığı anlamına gelir. Yerel halk sözlüğü belirtilmemişse varsayılan olarak globals sözlüğüne döner. Her iki sözlük de belirtilmezse, ifade eval()'un çağrıldığı ortamda yürütülür. Dönüş değeri, değerlendirilen ifadesinin sonucudur.

dolayısıyla kendi locals() sözlük var, bir jeneratör ifadesi (aynı zamanda dict anlama için de geçerlidir) kendi kapsamını sahip olduğuna dikkat etmek önemlidir Başlangıç ​​olarak.
  1. Bu nedenle dict yapıcı bu değişkenleri erişebilirler aynı sözlüğe küresel kapsamda çünkü hem globals() ve locals() dict noktalarını çalıştı. İşte

  2. yine o (boş) küresel kapsamı ve kendi yerel kapsamı kullanarak biter dolayısıyla hiçbir globals() ve locals() dict ile eval() arayarak ve bu kapsamları hiçbirinde böyle değişken kullanılabilir vardır edilir.

  3. Jeneratörlerin kendi kapsamları olduğunu unutmayın, bu nedenle locals() numaralı telefonu arayarak hiçbir fark yaratmaz, boş bir karardır.

Çözüm: Biz test1 en locals() bir değişkene yakalanan ve daha sonra sözlük anlama içi o sözlüğü kullanılır, bu yüzden şimdi bu değişkenlerin erişimi vardır, çünkü bu çalıştı

def test1(): 
    lvar1 = 1 
    lvar2 = 2 
    lvar3 = 3 
    test1_locals = locals() 
    myDict = dict((name, eval(name, test1_locals)) for name in ["lvar1", 
               "lvar2", 
               "lvar3"]) 
    print myDict 
    print(myDict["lvar1"]) 

.

+0

Açıklama için teşekkür ederiz! Bu şaşırtıcı! Bu hakkı anladıysam, dict() 'komutu içinde sadece global değişkenleri hesaba katar, bu yüzden yerelde olduğu için bir fonksiyon içindeki tüm değişkenleri dışarıda bırakır. (bu yüzden kapsamı belirtmek zorundayız?) – Adib

+1

Bir jeneratör ifadesini kendi yerlileri kümesine sahip yeni bir işlev alanı olarak düşünün, test1'in kendi ayrı yerlileri vardır. –

+0

Teşekkürler. Bu çok iyi bir açıklama. – atevm