อะไรคือความแตกต่างระหว่าง eval, exec และ compile?


428

ฉันได้ดูการประเมินรหัส Python แบบไดนามิกและพบกับeval()และcompile()ฟังก์ชั่นและexecคำสั่ง

ใครช่วยอธิบายความแตกต่างระหว่างevalและกับexecและโหมดที่แตกต่างกันได้compile()อย่างไร

คำตอบ:


517

คำตอบสั้น ๆ หรือ TL; DR

โดยทั่วไปevalจะใช้ในการEVAL uate แสดงออกหลามเดียวที่สร้างแบบไดนามิกและexecจะใช้ในการบริหาร ute สร้างแบบไดนามิกรหัสหลามเฉพาะสำหรับผลข้างเคียง

evalและexecมีความแตกต่างสองประการนี้:

  1. evalยอมรับเฉพาะการแสดงออกเดียว , execสามารถใช้การป้องกันรหัสที่มีงบหลาม: ลูปtry: except:, classและฟังก์ชั่น / วิธีdefinitions และอื่น ๆ

    การแสดงออกใน Python เป็นสิ่งที่คุณสามารถมีค่าในการกำหนดตัวแปร:

    a_variable = (anything you can put within these parentheses is an expression)
  2. eval ส่งคืนค่าของนิพจน์ที่กำหนดในขณะที่execละเว้นค่าส่งคืนจากรหัสของมันและส่งคืนเสมอNone(ใน Python 2 มันเป็นคำสั่งและไม่สามารถใช้เป็นนิพจน์ได้

ในรุ่น 1.0 - 2.7 execเป็นคำสั่งเนื่องจาก CPython จำเป็นต้องผลิตวัตถุรหัสชนิดอื่นสำหรับฟังก์ชั่นที่ใช้execสำหรับผลข้างเคียงภายในฟังก์ชั่น

ใน Python 3 execเป็นฟังก์ชั่น การใช้งานจะไม่มีผลกับการรวบรวมไบต์ของฟังก์ชั่นที่มีการใช้งาน


ดังนั้นโดยทั่วไป:

>>> a = 5
>>> eval('37 + a')   # it is an expression
42
>>> exec('37 + a')   # it is an expression statement; value is ignored (None is returned)
>>> exec('a = 47')   # modify a global variable as a side effect
>>> a
47
>>> eval('a = 47')  # you cannot evaluate a statement
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    a = 47
      ^
SyntaxError: invalid syntax

compileใน'exec'โหมดการรวบรวมจำนวนของงบใด ๆ ลงใน bytecode ที่ปริยายเสมอผลตอบแทนNoneในขณะที่ใน'eval'โหมดมันรวบรวมเดียวแสดงออกเข้า bytecode ว่าผลตอบแทนที่คุ้มค่าของการแสดงออกว่า

>>> eval(compile('42', '<string>', 'exec'))  # code returns None
>>> eval(compile('42', '<string>', 'eval'))  # code returns 42
42
>>> exec(compile('42', '<string>', 'eval'))  # code returns 42,
>>>                                          # but ignored by exec

ใน'eval'โหมด (และด้วยevalฟังก์ชั่นหากมีการส่งผ่านสตริง) การcompileยกข้อยกเว้นหากซอร์สโค้ดมีคำสั่งหรือสิ่งอื่นนอกเหนือจากการแสดงออกเดียว:

>>> compile('for i in range(3): print(i)', '<string>', 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

อันที่จริงคำสั่ง"EVAL ยอมรับเฉพาะการแสดงออกเดียว"ใช้เฉพาะเมื่อสตริง (ซึ่งมีงูหลามรหัสที่มา ) evalจะถูกส่งผ่านไปยัง จากนั้นจะถูกรวบรวมภายในเพื่อ bytecode โดยใช้compile(source, '<string>', 'eval')นี่คือสิ่งที่แตกต่างมาจากจริงๆ

ถ้าcodeวัตถุ (ซึ่งมีงูหลามbytecode ) จะถูกส่งผ่านไปยังexecหรือeval, พวกเขาประพฤติเหมือนกันยกเว้นความจริงที่ว่าexecไม่สนใจค่าตอบแทนที่ยังคงกลับมาNoneเสมอ ดังนั้นจึงเป็นไปได้ที่จะใช้evalเพื่อดำเนินการบางอย่างที่มีคำสั่งถ้าคุณเพียงแค่compileใส่ไว้ใน bytecode ก่อนแทนที่จะส่งผ่านเป็นสตริง:

>>> eval(compile('if 1: print("Hello")', '<string>', 'exec'))
Hello
>>>

ทำงานได้โดยไม่มีปัญหาแม้ว่ารหัสที่รวบรวมมีคำสั่ง มันก็ยังคงให้ผลตอบแทนเพราะนั่นคือค่าตอบแทนของวัตถุรหัสกลับมาจากNonecompile

ใน'eval'โหมด (และด้วยevalฟังก์ชั่นหากมีการส่งผ่านสตริง) การcompileยกข้อยกเว้นหากซอร์สโค้ดมีคำสั่งหรือสิ่งอื่นนอกเหนือจากการแสดงออกเดียว:

>>> compile('for i in range(3): print(i)', '<string>'. 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

คำตอบอีกต่อไปหรือรายละเอียดเต็มไปด้วยเลือด

exec และ eval

execฟังก์ชั่น (ซึ่งเป็นคำสั่งในหลาม 2 ) ถูกนำมาใช้สำหรับการดำเนินการคำสั่งที่สร้างขึ้นแบบไดนามิกหรือโปรแกรม:

>>> program = '''
for i in range(3):
    print("Python is cool")
'''
>>> exec(program)
Python is cool
Python is cool
Python is cool
>>> 

evalฟังก์ชั่นไม่เหมือนกันสำหรับการแสดงออกเดียว , และผลตอบแทนที่คุ้มค่าของการแสดงออกนี้:

>>> a = 2
>>> my_calculation = '42 * a'
>>> result = eval(my_calculation)
>>> result
84

execและevalทั้งสองยอมรับโปรแกรม / การแสดงออกที่จะทำงานไม่ว่าจะเป็นstr, unicodeหรือbytesวัตถุที่มีรหัสที่มาหรือเป็นcodeวัตถุที่มีงูหลาม bytecode

หากstr/ unicode/ bytesบรรจุซอร์สโค้ดถูกส่งไปที่execมันจะทำงานเทียบเท่ากับ:

exec(compile(source, '<string>', 'exec'))

และevalมีพฤติกรรมเทียบเท่ากับ:

eval(compile(source, '<string>', 'eval'))

เนื่องจากนิพจน์ทั้งหมดสามารถใช้เป็นคำสั่งใน Python (สิ่งเหล่านี้เรียกว่าExprโหนดในไวยากรณ์ของ Python นามธรรมตรงกันข้ามไม่เป็นความจริง) คุณสามารถใช้execหากคุณไม่ต้องการค่าส่งคืน กล่าวคือคุณสามารถใช้อย่างใดอย่างหนึ่งeval('my_func(42)')หรือexec('my_func(42)')ความแตกต่างที่evalส่งกลับค่าที่ส่งคืนโดยmy_funcและexecละทิ้งมัน:

>>> def my_func(arg):
...     print("Called with %d" % arg)
...     return arg * 2
... 
>>> exec('my_func(42)')
Called with 42
>>> eval('my_func(42)')
Called with 42
84
>>> 

2 เพียงexecยอมรับรหัสที่มาที่มีงบเช่นdef, for, while, importหรือclassคำสั่งที่ได้รับมอบหมาย (aka a = 42) หรือโปรแกรมทั้งหมด:

>>> exec('for i in range(3): print(i)')
0
1
2
>>> eval('for i in range(3): print(i)')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

ทั้งสองexecและevalยอมรับข้อโต้แย้งตำแหน่งเพิ่มเติม 2 ข้อ - globalsและlocals- ซึ่งเป็นขอบเขตโกลบอลและโลคัลตัวแปรที่โค้ดเห็น ค่าเริ่มต้นเหล่านี้เป็นglobals()และlocals()ภายในขอบเขตที่เรียกว่าexecหรือevalแต่พจนานุกรมใด ๆ สามารถใช้สำหรับglobalsและใด ๆmappingสำหรับlocals(รวมถึงdictแน่นอน) สิ่งเหล่านี้สามารถใช้เพื่อ จำกัด / แก้ไขตัวแปรที่โค้ดมองเห็น แต่มักจะใช้สำหรับการจับตัวแปรที่execโค้ด uted สร้างขึ้น:

>>> g = dict()
>>> l = dict()
>>> exec('global a; a, b = 123, 42', g, l)
>>> g['a']
123
>>> l
{'b': 42}

(ถ้าคุณแสดงค่าของทั้งหมดgมันจะนานกว่าเพราะexecและevalเพิ่มโมดูลในตัวเป็น__builtins__ไปยัง globals โดยอัตโนมัติหากมันหายไป)

ใน Python 2 ไวยากรณ์อย่างเป็นทางการสำหรับexecคำสั่งนั้นเป็นจริงexec code in globals, localsตามที่

>>> exec 'global a; a, b = 123, 42' in g, l

อย่างไรก็ตามไวยากรณ์อื่นexec(code, globals, locals)ได้รับการยอมรับเสมอเช่นกัน (ดูด้านล่าง)

compile

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)ในตัวสามารถนำมาใช้เพื่อเพิ่มความเร็วในการเรียกซ้ำของรหัสเดียวกันกับexecหรือevalโดยการรวบรวมแหล่งที่มาเป็นcodeวัตถุก่อน modeควบคุมพารามิเตอร์ชนิดของรหัส fragment compileฟังก์ชั่นยอมรับและชนิดของ bytecode มันผลิต ทางเลือกที่มี'eval', 'exec'และ'single':

  • 'eval'โหมดคาดหวังว่าจะแสดงออกเพียงครั้งเดียวและจะผลิต bytecode ว่าเมื่อทำงานจะคืนค่าของการแสดงออกที่ :

    >>> dis.dis(compile('a + b', '<string>', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 RETURN_VALUE
  • 'exec'ยอมรับไพ ธ อนชนิดใดก็ได้ที่สร้างจากนิพจน์เดียวไปยังโมดูลทั้งหมดของโค้ดและดำเนินการราวกับว่ามันเป็นประโยคระดับบนสุดของโมดูล วัตถุโค้ดส่งคืนNone:

    >>> dis.dis(compile('a + b', '<string>', 'exec'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 POP_TOP                             <- discard result
                  8 LOAD_CONST               0 (None)   <- load None on stack
                 11 RETURN_VALUE                        <- return top of stack
  • 'single'เป็นรูปแบบจำนวน จำกัด'exec'ซึ่งรับรหัสที่มาที่มีเพียงครั้งเดียวคำสั่ง (หรืองบหลายคั่นด้วย;) ถ้ามีคำสั่งที่ผ่านมาเป็นคำสั่งการแสดงออกที่ bytecode ส่งผลให้ยังพิมพ์reprของมูลค่าของการแสดงออกที่ไปออกมาตรฐาน (!)

    if- elif- elseห่วงโซ่ห่วงด้วยelseและtryด้วยexcept, elseและfinallyบล็อกถือเป็นคำเดียว

    แฟรกเมนต์ต้นทางมี 2 ประโยคระดับบนสุดเป็นข้อผิดพลาดสำหรับ'single'ยกเว้นใน Python 2 มีข้อบกพร่องที่บางครั้งอนุญาตให้มีคำสั่งระดับบนสุดจำนวนมากในโค้ด รวบรวมเฉพาะอันแรกเท่านั้น ส่วนที่เหลือจะถูกละเว้น:

    ใน Python 2.7.8:

    >>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    >>> a
    5

    และใน Python 3.4.2:

    >>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1
        a = 5
            ^
    SyntaxError: multiple statements found while compiling a single statement

    สิ่งนี้มีประโยชน์มากสำหรับการสร้างเชลล์ Python แบบโต้ตอบ อย่างไรก็ตามค่าของการแสดงออกจะไม่ถูกส่งกลับแม้ว่าคุณจะได้evalรับรหัส

ความแตกต่างที่ยิ่งใหญ่ที่สุดของexecและevalมาจากcompileฟังก์ชั่นและโหมดของมัน


นอกจากการคอมไพล์ซอร์สโค้ดไปยัง bytecode แล้วยังcompileรองรับการคอมไพล์ไวยากรณ์แบบนามธรรม (ต้นไม้แยกวิเคราะห์ของโค้ดไพ ธ อน) ลงในcodeวัตถุ และซอร์สโค้ดลงในต้นไม้ไวยากรณ์ที่เป็นนามธรรม (ast.parseเขียนใน Python และเพิ่งเรียกcompile(source, filename, mode, PyCF_ONLY_AST)); สิ่งเหล่านี้ใช้สำหรับการปรับเปลี่ยนซอร์สโค้ดได้ทันทีและสำหรับการสร้างโค้ดแบบไดนามิกเนื่องจากมักจะง่ายต่อการจัดการโค้ดเป็นแผนผังของโหนดแทนบรรทัดข้อความในกรณีที่ซับซ้อน


แม้ว่าevalจะอนุญาตให้คุณประเมินสตริงที่มีนิพจน์เดียว แต่คุณสามารถevalใช้ข้อความทั้งหมดหรือแม้กระทั่งโมดูลทั้งหมดที่เคยเป็นมาได้compileเข้าสู่ bytecode; นั่นคือด้วย Python 2 printเป็นคำสั่งและไม่สามารถevalนำโดยตรง:

>>> eval('for i in range(3): print("Python is cool")')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print("Python is cool")
      ^
SyntaxError: invalid syntax

compileด้วย'exec'โหมดเป็นcodeวัตถุและคุณก็สามารถeval มัน ; ฟังก์ชั่นจะกลับมาevalNone

>>> code = compile('for i in range(3): print("Python is cool")',
                   'foo.py', 'exec')
>>> eval(code)
Python is cool
Python is cool
Python is cool

หากมีการตรวจสอบevalและexecซอร์สโค้ดใน CPython 3 สิ่งนี้จะชัดเจนมาก พวกเขาทั้งคู่โทรPyEval_EvalCodeมีการขัดแย้งกันความแตกต่างเพียงอย่างเดียวว่าอย่างชัดเจนผลตอบแทนexecNone

ความแตกต่างของไวยากรณ์execระหว่าง Python 2 และ Python 3

หนึ่งในความแตกต่างที่สำคัญใน Python 2ก็execคือคำสั่งและevalเป็นฟังก์ชันในตัว (ทั้งสองเป็นฟังก์ชันในตัวใน Python 3) มันเป็นความจริงที่รู้จักกันดีว่าไวยากรณ์อย่างเป็นทางการของexecในหลาม exec code [in globals[, locals]]2

ซึ่งแตกต่างจากคนส่วนใหญ่ของงูหลาม 2 ไป 3 porting คู่มือ ดูเหมือน จะแนะนำที่execคำสั่งใน CPython 2 ยังสามารถใช้กับไวยากรณ์ที่มีลักษณะ ตรงเช่นexecภาวนาฟังก์ชั่นในหลาม 3. เหตุผลก็คือว่างูหลาม 0.9.9 มีexec(code, globals, locals)จั ในฟังก์ชั่น! และฟังก์ชั่นที่ถูกแทนที่ด้วยexecคำสั่งที่ไหนสักแห่งก่อนที่จะปล่อยงูหลาม 1.0

เพราะมันเป็นที่น่าพอใจจะไม่ทำลายความเข้ากันได้กับงูหลาม 0.9.9, กุยรถตู้ซัมเพิ่มสับการทำงานร่วมกันในปี 1993 : ถ้าcodeเป็น tuple ของความยาว 2 หรือ 3 และglobalsและlocalsไม่ได้ผ่านเข้าสู่execคำสั่งมิฉะนั้นcodeจะถูกตีความว่า ราวกับว่าองค์ประกอบที่ 2 และ 3 ของ tuple เป็นglobalsและlocalsตามลำดับ การแฮ็คเข้ากันไม่ได้กล่าวถึงแม้ในเอกสาร Python 1.4 (เวอร์ชั่นที่เก่าที่สุดที่มีในระบบออนไลน์) ; และดังนั้นจึงไม่เป็นที่รู้จักของนักเขียนหลายคนเกี่ยวกับคำแนะนำการย้ายและเครื่องมือจนกว่าจะได้รับการบันทึกอีกครั้งในเดือนพฤศจิกายน 2012 :

นิพจน์แรกอาจเป็น tuple ที่มีความยาว 2 หรือ 3 ในกรณีนี้ชิ้นส่วนเสริมจะต้องถูกตัดออก แบบฟอร์มที่exec(expr, globals)เทียบเท่ากับexec expr in globalsในขณะที่รูปแบบเทียบเท่ากับexec(expr, globals, locals) exec expr in globals, localsรูปแบบ tuple ของexecให้ความเข้ากันได้กับ Python 3 โดยที่execเป็นฟังก์ชันแทนที่จะเป็นคำสั่ง

ใช่ใน CPython 2.7 มันถูกอ้างถึงอย่างคล่องแคล่วว่าเป็นตัวเลือกความเข้ากันได้ไปข้างหน้า (ทำไมผู้คนสับสนว่ามีตัวเลือกความเข้ากันได้แบบย้อนกลับ) เมื่อจริง ๆ แล้วมันอยู่ที่นั่น ย้อนกลับเข้ากันได้สำหรับสองทศวรรษ

ดังนั้นในขณะที่ execเป็นคำสั่งใน Python 1 และ Python 2 และฟังก์ชั่นในตัวใน Python 3 และ Python 0.9.9

>>> exec("print(a)", globals(), {'a': 42})
42

มีพฤติกรรมที่เหมือนกันใน Python ทุกเวอร์ชันที่ออกวางตลาดอย่างกว้างขวาง และทำงานใน Jython 2.5.2, PyPy 2.3.1 (Python 2.7.6) และ IronPython 2.6.1 ด้วย (ขอชื่นชมพวกเขาหลังจากพฤติกรรมที่ไม่ได้บันทึกไว้ของ CPython อย่างใกล้ชิด)

สิ่งที่คุณไม่สามารถทำได้ใน Pythons 1.0 - 2.7 กับการแฮ็คเข้ากันได้คือการเก็บค่าส่งคืนของexecไว้ในตัวแปร:

Python 2.7.11+ (default, Apr 17 2016, 14:00:29) 
[GCC 5.3.1 20160413] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = exec('print(42)')
  File "<stdin>", line 1
    a = exec('print(42)')
           ^
SyntaxError: invalid syntax

(ซึ่งจะไม่มีประโยชน์ใน Python 3 เช่นเดียวกับexecส่งคืนเสมอNone) หรือผ่านการอ้างอิงถึงexec:

>>> call_later(exec, 'print(42)', delay=1000)
  File "<stdin>", line 1
    call_later(exec, 'print(42)', delay=1000)
                  ^
SyntaxError: invalid syntax

ซึ่งเป็นรูปแบบที่บางคนอาจใช้งานจริง

หรือใช้ในรายการความเข้าใจ:

>>> [exec(i) for i in ['print(42)', 'print(foo)']
  File "<stdin>", line 1
    [exec(i) for i in ['print(42)', 'print(foo)']
        ^
SyntaxError: invalid syntax

ซึ่งเป็นการละเมิดความเข้าใจในรายการ (ใช้forวนซ้ำแทน!)


เป็น [i for i in globals().values() if hasattr(i, '__call__')][0]คำสั่งหรือการแสดงออก? ถ้าเป็นการแสดงออกฉันจะใช้กับ@มัณฑนากรไม่ได้ทำไม
มาริโอ

มันคือการแสดงออก 42เป็นนิพจน์และคุณไม่สามารถใช้มัน@เป็นมัณฑนากรได้
Antti Haapala

ไวยากรณ์ของมัณฑนากรคือ decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE ; เช่นคุณไม่สามารถใช้นิพจน์โดยพลการเป็นตัวตกแต่งได้เพียงตัวระบุ (อาจเป็นจุด) ตามด้วยอาร์กิวเมนต์ตัวเลือกการโทร
Antti Haapala

1
ไม่ใช่สิ่งใดที่สามารถวางไว้ทางด้านขวาของการมอบหมายและยังคงคอมไพล์เป็นนิพจน์ ตัวอย่างเช่นa = b = cเป็นข้อความที่ถูกต้องสมบูรณ์เช่นเดียวกับด้านขวาb = c- ซึ่งไม่ใช่การแสดงออก
Tom

194
  1. execไม่ใช่นิพจน์: คำสั่งใน Python 2.x และฟังก์ชันใน Python 3.x มันรวบรวมและประเมินผลทันทีคำสั่งหรือชุดของคำสั่งที่มีอยู่ในสตริง ตัวอย่าง:

    exec('print(5)')           # prints 5.
    # exec 'print 5'     if you use Python 2.x, nor the exec neither the print is a function there
    exec('print(5)\nprint(6)')  # prints 5{newline}6.
    exec('if True: print(6)')  # prints 6.
    exec('5')                 # does nothing and returns nothing.
  2. evalเป็นฟังก์ชันในตัว ( ไม่ใช่ข้อความสั่ง) ซึ่งประเมินค่านิพจน์และส่งคืนค่าที่นิพจน์สร้าง ตัวอย่าง:

    x = eval('5')              # x <- 5
    x = eval('%d + 6' % x)     # x <- 11
    x = eval('abs(%d)' % -100) # x <- 100
    x = eval('x = 5')          # INVALID; assignment is not an expression.
    x = eval('if 1: x = 4')    # INVALID; if is a statement, not an expression.
  3. compileเป็นรุ่นระดับที่ต่ำกว่าและexec evalมันไม่ได้ดำเนินการหรือประเมินผลคำสั่งหรือการแสดงออกของคุณ แต่ส่งกลับวัตถุรหัสที่สามารถทำได้ โหมดมีดังนี้:

    1. compile(string, '', 'eval')eval(string)ผลตอบแทนที่ได้วัตถุรหัสที่จะได้รับการดำเนินการได้ที่คุณทำ โปรดทราบว่าคุณไม่สามารถใช้คำสั่งในโหมดนี้ นิพจน์ (เดี่ยว) เท่านั้นที่ถูกต้อง
    2. compile(string, '', 'exec')exec(string)ผลตอบแทนที่ได้วัตถุรหัสที่จะได้รับการดำเนินการได้ที่คุณทำ คุณสามารถใช้งบจำนวนเท่าใดก็ได้ที่นี่
    3. compile(string, '', 'single')เหมือนexecโหมด แต่มันจะไม่สนใจทุกอย่างยกเว้นสำหรับคำสั่งแรก โปรดทราบว่าif/elseคำสั่งพร้อมผลลัพธ์จะถือว่าเป็นคำสั่งเดียว

40
ใน Python 3 exec()ตอนนี้เป็นฟังก์ชั่น
ทิม Pietzcker

2
เนื่องจาก (ตามที่คุณชี้ให้เห็น) execเป็นคำสั่งในเวอร์ชันที่คุณกำหนดเป้าหมายมันเป็นการหลอกลวงที่จะรวม parens เหล่านั้นและหากคุณพยายามใช้in globals, localsมัน
Mike Graham

2
@MikeGraham exec สนับสนุนวงเล็บและฟังก์ชั่นเช่นการภาวนาในหลาม 2
Antti Haapala

2
@AnttiHaapala ตราบเท่าที่การกำหนด 'รองรับวงเล็บ' เพราะคุณสามารถทำได้x = (y)นั่นอาจเป็นจริง อีกฟังก์ชั่นเปิดใช้งานคือprint; เปรียบเทียบผลลัพธ์ของprint(1, 2, 3)ใน python 2 และ 3
habnabit

1
@habnabit ไม่เป็นเช่นนั้น โปรดอ่านคำตอบของฉันที่นี่และประหลาดใจ
Antti Haapala

50

exec เป็นคำสั่งและจะไม่ส่งคืนสิ่งใด eval ใช้สำหรับการแสดงออกและคืนค่าการแสดงออก

การแสดงออกหมายถึง "บางสิ่ง" ในขณะที่คำสั่งหมายถึง "ทำอะไรบางอย่าง"


9
ย่อหน้าที่สองนั้นเป็นการทำให้เข้าใจง่ายซึ่งมันเกือบจะกลายเป็นเรื่องโกหกการแสดงออกสามารถทำอะไรได้มากถ้ามันมีการเรียกใช้ฟังก์ชัน
Antti Haapala
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.