ฉันได้ดูการประเมินรหัส Python แบบไดนามิกและพบกับeval()
และcompile()
ฟังก์ชั่นและexec
คำสั่ง
ใครช่วยอธิบายความแตกต่างระหว่างeval
และกับexec
และโหมดที่แตกต่างกันได้compile()
อย่างไร
ฉันได้ดูการประเมินรหัส Python แบบไดนามิกและพบกับeval()
และcompile()
ฟังก์ชั่นและexec
คำสั่ง
ใครช่วยอธิบายความแตกต่างระหว่างeval
และกับexec
และโหมดที่แตกต่างกันได้compile()
อย่างไร
คำตอบ:
โดยทั่วไปeval
จะใช้ในการEVAL uate แสดงออกหลามเดียวที่สร้างแบบไดนามิกและexec
จะใช้ในการบริหาร ute สร้างแบบไดนามิกรหัสหลามเฉพาะสำหรับผลข้างเคียง
eval
และexec
มีความแตกต่างสองประการนี้:
eval
ยอมรับเฉพาะการแสดงออกเดียว , exec
สามารถใช้การป้องกันรหัสที่มีงบหลาม: ลูปtry: except:
, class
และฟังก์ชั่น / วิธีdef
initions และอื่น ๆ
การแสดงออกใน Python เป็นสิ่งที่คุณสามารถมีค่าในการกำหนดตัวแปร:
a_variable = (anything you can put within these parentheses is an expression)
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
>>>
ทำงานได้โดยไม่มีปัญหาแม้ว่ารหัสที่รวบรวมมีคำสั่ง มันก็ยังคงให้ผลตอบแทนเพราะนั่นคือค่าตอบแทนของวัตถุรหัสกลับมาจากNone
compile
ใน'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
มัน ; ฟังก์ชั่นจะกลับมาeval
None
>>> 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
มีการขัดแย้งกันความแตกต่างเพียงอย่างเดียวว่าอย่างชัดเจนผลตอบแทนexec
None
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
วนซ้ำแทน!)
42
เป็นนิพจน์และคุณไม่สามารถใช้มัน@
เป็นมัณฑนากรได้
decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE
; เช่นคุณไม่สามารถใช้นิพจน์โดยพลการเป็นตัวตกแต่งได้เพียงตัวระบุ (อาจเป็นจุด) ตามด้วยอาร์กิวเมนต์ตัวเลือกการโทร
a = b = c
เป็นข้อความที่ถูกต้องสมบูรณ์เช่นเดียวกับด้านขวาb = c
- ซึ่งไม่ใช่การแสดงออก
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.
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.
compile
เป็นรุ่นระดับที่ต่ำกว่าและexec
eval
มันไม่ได้ดำเนินการหรือประเมินผลคำสั่งหรือการแสดงออกของคุณ แต่ส่งกลับวัตถุรหัสที่สามารถทำได้ โหมดมีดังนี้:
compile(string, '', 'eval')
eval(string)
ผลตอบแทนที่ได้วัตถุรหัสที่จะได้รับการดำเนินการได้ที่คุณทำ โปรดทราบว่าคุณไม่สามารถใช้คำสั่งในโหมดนี้ นิพจน์ (เดี่ยว) เท่านั้นที่ถูกต้องcompile(string, '', 'exec')
exec(string)
ผลตอบแทนที่ได้วัตถุรหัสที่จะได้รับการดำเนินการได้ที่คุณทำ คุณสามารถใช้งบจำนวนเท่าใดก็ได้ที่นี่compile(string, '', 'single')
เหมือนexec
โหมด แต่มันจะไม่สนใจทุกอย่างยกเว้นสำหรับคำสั่งแรก โปรดทราบว่าif
/else
คำสั่งพร้อมผลลัพธ์จะถือว่าเป็นคำสั่งเดียวexec()
ตอนนี้เป็นฟังก์ชั่น
exec
เป็นคำสั่งในเวอร์ชันที่คุณกำหนดเป้าหมายมันเป็นการหลอกลวงที่จะรวม parens เหล่านั้นและหากคุณพยายามใช้in globals, locals
มัน
exec
สนับสนุนวงเล็บและฟังก์ชั่นเช่นการภาวนาในหลาม 2
x = (y)
นั่นอาจเป็นจริง อีกฟังก์ชั่นเปิดใช้งานคือprint
; เปรียบเทียบผลลัพธ์ของprint(1, 2, 3)
ใน python 2 และ 3
exec เป็นคำสั่งและจะไม่ส่งคืนสิ่งใด eval ใช้สำหรับการแสดงออกและคืนค่าการแสดงออก
การแสดงออกหมายถึง "บางสิ่ง" ในขณะที่คำสั่งหมายถึง "ทำอะไรบางอย่าง"
[i for i in globals().values() if hasattr(i, '__call__')][0]
คำสั่งหรือการแสดงออก? ถ้าเป็นการแสดงออกฉันจะใช้กับ@
มัณฑนากรไม่ได้ทำไม