Whats the difference between eval exec and compile
Python, famed for its versatility and readability, presents a trio of almighty capabilities – eval()
, exec()
, and compile()
– that frequently origin disorder amongst builders. These capabilities, piece seemingly akin, service chiseled functions associated to dynamic codification execution. Knowing their nuances is important for penning businesslike and unafraid Python functions. This article delves into the center variations betwixt these capabilities, exploring their functionalities, usage instances, and possible safety implications.
eval()
: Evaluating Elemental Expressions
eval()
is designed to measure a azygous Python look. Deliberation of it arsenic a miniature calculator inside your codification. It takes a drawstring arsenic enter, interprets it arsenic a Python look, executes it, and returns the consequence. This is utile for dynamic calculations oregon once you demand to measure person-equipped enter arsenic a Python look, albeit with warning.
For case, eval("2 + three")
would instrument 5. Nevertheless, its simplicity comes with safety dangers, particularly once dealing with person enter straight. Ideate eval(user_input)
; if a malicious person inputs __import__('os').scheme('rm -rf /')
, it might pb to disastrous penalties.
Cardinal Usage Instances:
- Elemental calculations primarily based connected dynamic values.
- Evaluating mathematical formulation saved arsenic strings.
exec()
: Executing Blocks of Codification
exec()
takes a measure additional, permitting you to execute an full artifact of Python codification. Dissimilar eval()
, which returns a worth, exec()
doesn’t instrument thing. It’s chiefly utilized for dynamically producing and moving codification, specified arsenic creating features oregon courses connected the alert.
For illustration, exec("def my_function(): mark('Hullo')")
would specify a fresh relation referred to as my_function()
. Akin to eval()
, exec()
besides carries safety dangers once utilized with untrusted enter. Ever sanitize and validate person-supplied codification earlier execution.
Cardinal Usage Circumstances:
- Dynamically defining capabilities and lessons.
- Executing codification saved successful outer records-data oregon databases.
compile()
: Compiling Codification for Future Usage
compile()
acts arsenic a pre-processor, changing origin codification into bytecode, an intermediate cooperation that Python tin execute much effectively. Piece you tin execute the compiled codification instantly, the capital vantage of compile()
lies successful caching the bytecode for repeated execution. This improves show, particularly for codification that wants to beryllium tally aggregate occasions.
compiled_code = compile("mark('Hullo')", "<string>", "exec")</string>
creates a codification entity. Past, exec(compiled_code)
would execute the compiled codification. This attack is generous for often utilized codification snippets, lowering explanation overhead.
Cardinal Usage Circumstances:
- Optimizing often executed codification.
- Pre-compiling codification for usage successful dynamic environments.
Selecting the Correct Relation
Selecting betwixt eval()
, exec()
, and compile()
relies upon connected the circumstantial project. For evaluating azygous expressions, eval()
is adequate. For executing blocks of codification, exec()
is the due prime. And once optimizing show for repeated codification execution, compile()
offers the champion resolution.
Prioritize safety by avoiding the usage of eval()
and exec()
with untrusted inputs. Sanitize and validate outer information meticulously to forestall possible vulnerabilities. See utilizing safer alternate options similar ast.literal_eval()
for evaluating elemental expressions.
For additional speechmaking connected Python safety champion practices, cheque retired the OWASP Apical 10. You tin besides larn much astir Python’s ast
module for unafraid codification valuation successful the authoritative documentation.
Infographic Placeholder: Ocular examination of eval()
, exec()
, and compile()
.
Larn much astir circumstantial Python vulnerabilities present.
FAQ
Q: Tin I usage compile()
with eval()
?
A: Sure, you tin compile an look utilizing compile()
and past measure it utilizing eval()
. This is chiefly generous for show optimization once an look wants to beryllium evaluated aggregate instances.
Successful essence, knowing the distinctions betwixt eval()
, exec()
, and compile()
empowers you to compose businesslike, unafraid, and dynamic Python codification. By selecting the due relation for the project astatine manus and pursuing safety champion practices, you tin harness the afloat possible of these almighty instruments piece mitigating possible dangers. Research these capabilities, experimentation with their capabilities, and elevate your Python programming expertise to fresh heights. Dive deeper into precocious Python ideas and detect however dynamic codification execution tin heighten your initiatives. Larn much astir these almighty features present.
Question & Answer :
I’ve been wanting astatine dynamic valuation of Python codification, and travel crossed the eval()
and compile()
capabilities, and the exec
message.
Tin person delight explicate the quality betwixt eval
and exec
, and however the antithetic modes of compile()
acceptable successful?
The abbreviated reply, oregon TL;DR
Fundamentally, eval
is utilized to evaluate a azygous dynamically generated Python look, and exec
is utilized to execute dynamically generated Python codification lone for its broadside results.
eval
and exec
person these 2 variations:
-
eval
accepts lone a azygous look,exec
tin return a codification artifact that has Python statements: loops,attempt: but:
,people
and relation/methodologydef
initions and truthful connected.An look successful Python is any you tin person arsenic the worth successful a adaptable duty:
a_variable = (thing you tin option inside these parentheses is an look)
-
eval
returns the worth of the fixed look, whereasexec
ignores the instrument worth from its codification, and ever returnsNo
(successful Python 2 it is a message and can’t beryllium utilized arsenic an look, truthful it truly does not instrument thing).
Successful variations 1.zero - 2.7, exec
was a message, due to the fact that CPython wanted to food a antithetic benignant of codification entity for capabilities that utilized exec
for its broadside results wrong the relation.
Successful Python three, exec
is a relation; its usage has nary consequence connected the compiled bytecode of the relation wherever it is utilized.
Frankincense fundamentally:
>>> a = 5 >>> eval('37 + a') # it is an look forty two >>> exec('37 + a') # it is an look message; worth is ignored (No is returned) >>> exec('a = forty seven') # modify a planetary adaptable arsenic a broadside consequence >>> a forty seven >>> eval('a = forty seven') # you can't measure a message Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 a = forty seven ^ SyntaxError: invalid syntax
The compile
successful 'exec'
manner compiles immoderate figure of statements into a bytecode that implicitly ever returns No
, whereas successful 'eval'
manner it compiles a azygous look into bytecode that returns the worth of that look.
>>> eval(compile('forty two', '<drawstring>', 'exec')) # codification returns No >>> eval(compile('forty two', '<drawstring>', 'eval')) # codification returns forty two forty two >>> exec(compile('forty two', '<drawstring>', 'eval')) # codification returns forty two, >>> # however ignored by exec
Successful the 'eval'
manner (and frankincense with the eval
relation if a drawstring is handed successful), the compile
raises an objection if the origin codification incorporates statements oregon thing other past a azygous look:
>>> compile('for i successful scope(three): mark(i)', '<drawstring>', 'eval') Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 for i successful scope(three): mark(i) ^ SyntaxError: invalid syntax
Really the message “eval accepts lone a azygous look” applies lone once a drawstring (which accommodates Python origin codification) is handed to eval
. Past it is internally compiled to bytecode utilizing compile(origin, '<drawstring>', 'eval')
This is wherever the quality truly comes from.
If a codification
entity (which comprises Python bytecode) is handed to exec
oregon eval
, they behave identically, excepting for the information that exec
ignores the instrument worth, inactive returning No
ever. Truthful it is imaginable usage eval
to execute thing that has statements, if you conscionable compile
d it into bytecode earlier alternatively of passing it arsenic a drawstring:
>>> eval(compile('if 1: mark("Hullo")', '<drawstring>', 'exec')) Hullo >>>
plant with out issues, equal although the compiled codification accommodates statements. It inactive returns No
, due to the fact that that is the instrument worth of the codification entity returned from compile
.
Successful the 'eval'
manner (and frankincense with the eval
relation if a drawstring is handed successful), the compile
raises an objection if the origin codification incorporates statements oregon thing other past a azygous look:
>>> compile('for i successful scope(three): mark(i)', '<drawstring>'. 'eval') Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 for i successful scope(three): mark(i) ^ SyntaxError: invalid syntax
The longer reply, a.ok.a the gory particulars
exec
and eval
The exec
relation (which was a message successful Python 2) is utilized for executing a dynamically created message oregon programme:
>>> programme = ''' for i successful scope(three): mark("Python is chill") ''' >>> exec(programme) Python is chill Python is chill Python is chill >>>
The eval
relation does the aforesaid for a azygous look, and returns the worth of the look:
>>> a = 2 >>> my_calculation = 'forty two * a' >>> consequence = eval(my_calculation) >>> consequence eighty four
exec
and eval
some judge the programme/look to beryllium tally both arsenic a str
, unicode
oregon bytes
entity containing origin codification, oregon arsenic a codification
entity which comprises Python bytecode.
If a str
/unicode
/bytes
containing origin codification was handed to exec
, it behaves equivalently to:
exec(compile(origin, '<drawstring>', 'exec'))
and eval
likewise behaves equal to:
eval(compile(origin, '<drawstring>', 'eval'))
Since each expressions tin beryllium utilized arsenic statements successful Python (these are referred to as the Expr
nodes successful the Python summary grammar; the other is not actual), you tin ever usage exec
if you bash not demand the instrument worth. That is to opportunity, you tin usage both eval('my_func(forty two)')
oregon exec('my_func(forty two)')
, the quality being that eval
returns the worth returned by my_func
, and exec
discards it:
>>> def my_func(arg): ... mark("Referred to as with %d" % arg) ... instrument arg * 2 ... >>> exec('my_func(forty two)') Known as with forty two >>> eval('my_func(forty two)') Referred to as with forty two eighty four >>>
Of the 2, lone exec
accepts origin codification that comprises statements, similar def
, for
, piece
, import
, oregon people
, the duty message (a.ok.a a = forty two
), oregon full applications:
>>> exec('for i successful scope(three): mark(i)') zero 1 2 >>> eval('for i successful scope(three): mark(i)') Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 for i successful scope(three): mark(i) ^ SyntaxError: invalid syntax
Some exec
and eval
judge 2 further positional arguments - globals
and locals
- which are the planetary and section adaptable scopes that the codification sees. These default to the globals()
and locals()
inside the range that referred to as exec
oregon eval
, however immoderate dictionary tin beryllium utilized for globals
and immoderate mapping
for locals
(together with dict
of class). These tin beryllium utilized not lone to limit/modify the variables that the codification sees, however are frequently besides utilized for capturing the variables that the exec
uted codification creates:
>>> g = dict() >>> l = dict() >>> exec('planetary a; a, b = 123, forty two', g, l) >>> g['a'] 123 >>> l {'b': forty two}
(If you show the worth of the full g
, it would beryllium overmuch longer, due to the fact that exec
and eval
adhd the constructed-ins module arsenic __builtins__
to the globals mechanically if it is lacking).
Successful Python 2, the authoritative syntax for the exec
message is really exec codification successful globals, locals
, arsenic successful
>>> exec 'planetary a; a, b = 123, forty two' successful g, l
Nevertheless the alternate syntax exec(codification, globals, locals)
has ever been accepted excessively (seat beneath).
compile
The compile(origin, filename, manner, flags=zero, dont_inherit=Mendacious, optimize=-1)
constructed-successful tin beryllium utilized to velocity ahead repeated invocations of the aforesaid codification with exec
oregon eval
by compiling the origin into a codification
entity beforehand. The manner
parameter controls the benignant of codification fragment the compile
relation accepts and the benignant of bytecode it produces. The decisions are 'eval'
, 'exec'
and 'azygous'
:
-
'eval'
manner expects a azygous look, and volition food bytecode that once tally volition instrument the worth of that look:>>> dis.dis(compile('a + b', '<drawstring>', 'eval')) 1 zero LOAD_NAME zero (a) three LOAD_NAME 1 (b) 6 BINARY_ADD 7 RETURN_VALUE
-
'exec'
accepts immoderate sorts of python constructs from azygous expressions to entire modules of codification, and executes them arsenic if they had been module apical-flat statements. The codification entity returnsNo
:>>> dis.dis(compile('a + b', '<drawstring>', 'exec')) 1 zero LOAD_NAME zero (a) three LOAD_NAME 1 (b) 6 BINARY_ADD 7 POP_TOP <- discard consequence eight LOAD_CONST zero (No) <- burden No connected stack eleven RETURN_VALUE <- instrument apical of stack
-
'azygous'
is a constricted signifier of'exec'
which accepts a origin codification containing a azygous message (oregon aggregate statements separated by;
) if the past message is an look message, the ensuing bytecode besides prints therepr
of the worth of that look to the modular output(!).An
if
-elif
-other
concatenation, a loop withother
, andattempt
with itsbut
,other
andeventually
blocks is thought of a azygous message.A origin fragment containing 2 apical-flat statements is an mistake for the
'azygous'
, but successful Python 2 location is a bug that generally permits aggregate toplevel statements successful the codification; lone the archetypal is compiled; the remainder are ignored:Successful Python 2.7.eight:
>>> exec(compile('a = 5\na = 6', '<drawstring>', 'azygous')) >>> a 5
And successful Python three.four.2:
>>> exec(compile('a = 5\na = 6', '<drawstring>', 'azygous')) Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 a = 5 ^ SyntaxError: aggregate statements recovered piece compiling a azygous message
This is precise utile for making interactive Python shells. Nevertheless, the worth of the look is not returned, equal if you
eval
the ensuing codification.
Frankincense top discrimination of exec
and eval
really comes from the compile
relation and its modes.
Successful summation to compiling origin codification to bytecode, compile
helps compiling summary syntax timber (parse bushes of Python codification) into codification
objects; and origin codification into summary syntax bushes (the ast.parse
is written successful Python and conscionable calls compile(origin, filename, manner, PyCF_ONLY_AST)
); these are utilized for illustration for modifying origin codification connected the alert, and besides for dynamic codification instauration, arsenic it is frequently simpler to grip the codification arsenic a actor of nodes alternatively of traces of matter successful analyzable instances.
Piece eval
lone permits you to measure a drawstring that accommodates a azygous look, you tin eval
a entire message, oregon equal a entire module that has been compile
d into bytecode; that is, with Python 2, mark
is a message, and can not beryllium eval
led straight:
>>> eval('for i successful scope(three): mark("Python is chill")') Traceback (about new call past): Record "<stdin>", formation 1, successful <module> Record "<drawstring>", formation 1 for i successful scope(three): mark("Python is chill") ^ SyntaxError: invalid syntax
compile
it with 'exec'
manner into a codification
entity and you tin eval
it; the eval
relation volition instrument No
.
>>> codification = compile('for i successful scope(three): mark("Python is chill")', 'foo.py', 'exec') >>> eval(codification) Python is chill Python is chill Python is chill
If 1 seems into eval
and exec
origin codification successful CPython three, this is precise evident; they some call PyEval_EvalCode
with aforesaid arguments, the lone quality being that exec
explicitly returns No
.
Syntax variations of exec
betwixt Python 2 and Python three
1 of the great variations successful Python 2 is that exec
is a message and eval
is a constructed-successful relation (some are constructed-successful capabilities successful Python three). It is a fine-recognized information that the authoritative syntax of exec
successful Python 2 is exec codification [successful globals[, locals]]
.
Dissimilar bulk of the Python 2-to-three porting guides look to propose, the exec
message successful CPython 2 tin beryllium besides utilized with syntax that appears to be like precisely similar the exec
relation invocation successful Python three. The ground is that Python zero.9.9 had the exec(codification, globals, locals)
constructed-successful relation! And that constructed-successful relation was changed with exec
message location earlier Python 1.zero merchandise.
Since it was fascinating to not interruption backwards compatibility with Python zero.9.9, Guido van Rossum added a compatibility hack successful 1993: if the codification
was a tuple of dimension 2 oregon three, and globals
and locals
have been not handed into the exec
message other, the codification
would beryllium interpreted arsenic if the 2nd and third component of the tuple have been the globals
and locals
respectively. The compatibility hack was not talked about equal successful Python 1.four documentation (the earliest disposable interpretation on-line); and frankincense was not identified to galore writers of the porting guides and instruments, till it was documented once more successful November 2012:
The archetypal look whitethorn besides beryllium a tuple of dimension 2 oregon three. Successful this lawsuit, the elective components essential beryllium omitted. The signifier
exec(expr, globals)
is equal toexec expr successful globals
, piece the signifierexec(expr, globals, locals)
is equal toexec expr successful globals, locals
. The tuple signifier ofexec
offers compatibility with Python three, whereverexec
is a relation instead than a message.
Sure, successful CPython 2.7 that it is handily referred to arsenic being a guardant-compatibility action (wherefore confuse group complete that location is a backward compatibility action astatine each), once it really had been location for backward-compatibility for 2 a long time.
Frankincense piece exec
is a message successful Python 1 and Python 2, and a constructed-successful relation successful Python three and Python zero.9.9,
>>> exec("mark(a)", globals(), {'a': forty two}) forty two
has had an identical behaviour successful perchance all wide launched Python interpretation always; and plant successful Jython 2.5.2, PyPy 2.three.1 (Python 2.7.6) and IronPython 2.6.1 excessively (kudos to them pursuing the undocumented behaviour of CPython intimately).
What you can not bash successful Pythons 1.zero - 2.7 with its compatibility hack, is to shop the instrument worth of exec
into a adaptable:
Python 2.7.eleven+ (default, Apr 17 2016, 14:00:29) [GCC 5.three.1 20160413] connected linux2 Kind "aid", "copyright", "credit" oregon "licence" for much accusation. >>> a = exec('mark(forty two)') Record "<stdin>", formation 1 a = exec('mark(forty two)') ^ SyntaxError: invalid syntax
(which wouldn’t beryllium utile successful Python three both, arsenic exec
ever returns No
), oregon walk a mention to exec
:
>>> call_later(exec, 'mark(forty two)', hold=a thousand) Record "<stdin>", formation 1 call_later(exec, 'mark(forty two)', hold=one thousand) ^ SyntaxError: invalid syntax
Which a form that person mightiness really person utilized, although improbable;
Oregon usage it successful a database comprehension:
>>> [exec(i) for i successful ['mark(forty two)', 'mark(foo)'] Record "<stdin>", formation 1 [exec(i) for i successful ['mark(forty two)', 'mark(foo)'] ^ SyntaxError: invalid syntax
which is maltreatment of database comprehensions (usage a for
loop alternatively!).