Değişkenler globals olarak veya Python'un işlevi eval() işlevine yerel olarak iletilirse neden bir fark yaratır? Python's eval()? Kullanırken yerliler ve globals arasındaki fark nedir?
Ayrıca, described in the documenation olarak Python, açıkça verilmediği takdirde, __builtins__
numaralı telefonu globals'a kopyalayacaktır. Fakat göremediğim başka bir farklılık da olmalı. Aşağıdaki örnek işlevi göz önünde bulundurun. Bir dize code
alır ve bir işlev nesnesi döndürür. Yerleşiklere izin verilmez (ör. abs()
), ancak tüm işlevler math
paketinden.
def make_fn(code):
import math
ALLOWED_LOCALS = {v:getattr(math, v)
for v in filter(lambda x: not x.startswith('_'), dir(math))
}
return eval('lambda x: %s' % code, {'__builtins__': None}, ALLOWED_LOCALS)
Çalışıyor herhangi bir yerel veya global nesneleri kullanarak değil beklendiği gibi:
fn = make_fn('x + 3')
fn(5) # outputs 8
Ama math
işlevleri kullanarak çalışmaz:
fn = make_fn('cos(x)')
fn(5)
Bu şu istisna verir:
<string> in <lambda>(x)
NameError: global name 'cos' is not defined
0 globaller aynı eşleme geçerkenAma çalışır: Yukarıdaki gibi
def make_fn(code):
import math
ALLOWED = {v:getattr(math, v)
for v in filter(lambda x: not x.startswith('_'), dir(math))
}
ALLOWED['__builtins__'] = None
return eval('lambda x: %s' % code, ALLOWED, {})
aynı örnek: detaylı olarak burada ne olur
fn = make_fn('cos(x)')
fn(5) # outputs 0.28366218546322625
?
Dokümantasyonda, "globals sözlüğü var ve" __builtins__ "bulunmuyor. Bu, "__builtins__" anahtarının mevcut olmadığı anlamına gelir, ancak örneğinizde, bunu None olarak ayarladığınız anlamına gelir. ÖNERİLEN [‘__ builtins__’] = None DEĞİŞTİRMELİ [‘__ builtins__’] ile değiştirilmemesini öneririm ve tekrar deneyin. – jorispilot
@jorispilot Sorunum, __builtins__'ye bağlı değil. Daha önce değindim, çünkü bu globals'ın özel bir kasası var. __builtins__ öğesini None olarak ayarladığım yol, 'abs' gibi yerleşik işlevleri yasaklamak istiyorsanız, doğru değildir. "çünkü" yerleşik bir işlev değildir, matematik modülünün bir parçasıdır. – lumbric