สั่งอย่างนี้หมายความว่าอะไรครับ

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
>>> a = {}
>>> a
{}
>>> exec "b=4" in a
>>> a.keys()
['__builtins__', 'b']
>>> a['b']
4
>>> a
.(lot of error msg)......'OverflowError': <class exceptions.OverflowError at 0xb7d4c9bc>}, 'b': 4}

(python 2.4)
ประโยค exec "b=4" in a มันทำอะไร?
แล้ว __builtins__ ที่เกิดขึ้นใน dict มันคืออะไร

sugree's picture

อ๋อ อันนี้เป็นของที่ผมชอบใช้ a ในโค้ดข้างบนเปรียบเสมือน context ที่เก็บตัวแปรทั้งหมดในระบบไว้ซึ่งปกติจะเป็น globals() เพราะ exec เป็น keyword พิเศษเอาไว้สำหรับรันโค้ดที่ระบุภายใต้ context แยกต่างหาก ถ้าไม่ระบุ in ตามหลังก็จะไปใช้ globals() แทน เรียกใช้ได้หลายแบบ

exec_stmt ::= "exec" expression ["in" global_and_local ["," local]]

ถ้าไม่ระบุ global_and_local กับ local ก็จะใช้ globals() กับ locals() ณ ขณะนั้น แต่ถ้าบอกแค่ global_and_local ก็จะย้ายทั้งคู่มาอยู่ที่ตัวแปรนี้ ซึ่งควรจะเป็น dict ส่วนถ้าบอกทั้งคู่ก็จะใช้เป็น global และ local ตามลำดับ

จากโค้ดข้างบนมันก็คือแบบข้างล่างครับ

>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None}
>>> b=4
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'b': 4, '__doc__': None}

ซึ่งที่เห็นยาวๆ ในนั้นไม่ใช่ error ครับมันเป็นของที่อยู่ใน __builtins__ ลองดูแบบนี้บ้าง

>>> a = {}
>>> exec "b=4" in a
>>> a['b']
4

ถ้าอยากรู้ว่าใน __builtins__ มีอะไรก็แค่ใช้ dir() ส่วน a['__builtins__'] ใช้ .keys()

>>> a['__builtins__'].keys()
['IndexError', 'help', 'vars', 'SyntaxError', 'unicode', 'UnicodeDecodeError', 'isinstance', 'copyright', 'NameError', 'dict', 'input', 'oct', 'SystemExit', 'StandardError', 'repr', 'sorted', 'False', 'RuntimeWarning', 'list', 'iter', 'reload', 'Warning', 'round', 'dir', 'cmp', 'set', 'reduce', 'intern', 'issubclass', 'Ellipsis', 'EOFError', 'locals', 'slice', 'FloatingPointError', 'sum', 'OverflowWarning', 'getattr', 'abs', 'exit', 'True', 'FutureWarning', 'None', 'hash', 'len', 'credits', 'frozenset', '__name__', 'ord', 'super', '_', 'TypeError', 'license', 'KeyboardInterrupt', 'UserWarning', 'filter', 'range', 'staticmethod', 'SystemError', 'pow', 'RuntimeError', 'float', 'StopIteration', 'globals', 'divmod', 'enumerate', 'apply', 'LookupError', 'open', 'quit', 'basestring', 'UnicodeError', 'zip', 'hex', 'long', 'ReferenceError', 'ImportError', 'chr', 'xrange', 'type', '__doc__', 'Exception', 'tuple', 'UnicodeTranslateError', 'reversed', 'UnicodeEncodeError', 'IOError', 'hasattr', 'delattr', 'setattr', 'raw_input', 'SyntaxWarning', 'compile', 'ArithmeticError', 'str', 'property', 'MemoryError', 'int', '__import__', 'KeyError', 'coerce', 'PendingDeprecationWarning', 'file', 'EnvironmentError', 'unichr', 'id', 'OSError', 'DeprecationWarning', 'min', 'execfile', 'complex', 'bool', 'ValueError', 'NotImplemented', 'map', 'buffer', 'max', 'object', 'TabError', 'callable', 'ZeroDivisionError', 'eval', '__debug__', 'IndentationError', 'AssertionError', 'classmethod', 'UnboundLocalError', 'NotImplementedError', 'AttributeError', 'OverflowError']
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

ซึ่งคืออันเดียวกันครับ ถ้าอยากให้สวยๆ ก็ระบุทั้ง global และ local ครับ จะได้สวยๆ

>>> a,b = {},{}
>>> exec "b=4" in a,b
>>> a.keys()
['__builtins__']
>>> b.keys()
['b']
>>> a
{'__builtins__': {'IndexError': <class exceptions.IndexError at 0xb7da38fc>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <class exceptions.SyntaxError at 0xb7da377c>, 'unicode': <type 'unicode'>, 'UnicodeDecodeError': <class exceptions.UnicodeDecodeError at 0xb7da3cbc>, 'isinstance': <built-in function isinstance>, 'copyright': Copyright (c) 2001-2006 Python Software Foundation.
All Rights Reserved.
 
Copyright (c) 2000 BeOpen.com.
All Rights Reserved.
 
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.
 
Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'NameError': <class exceptions.NameError at 0xb7da365c>, 'dict': <type 'dict'>, 'input': <built-in function input>, 'oct': <built-in function oct>, 'SystemExit': <class exceptions.SystemExit at 0xb7da332c>, 'StandardError': <class exceptions.StandardError at 0xb7da32cc>, 'repr': <built-in function repr>, 'sorted': <built-in function sorted>, 'False': False, 'RuntimeWarning': <class exceptions.RuntimeWarning at 0xb7da3fbc>, 'list': <type 'list'>, 'iter': <built-in function iter>, 'reload': <built-in function reload>, 'Warning': <class exceptions.Warning at 0xb7da3e3c>, 'round': <built-in function round>, 'dir': <built-in function dir>, 'cmp': <built-in function cmp>, 'set': <type 'set'>, 'reduce': <built-in function reduce>, 'intern': <built-in function intern>, 'issubclass': <built-in function issubclass>, 'Ellipsis': Ellipsis, 'EOFError': <class exceptions.EOFError at 0xb7da353c>, 'locals': <built-in function locals>, 'slice': <type 'slice'>, 'FloatingPointError': <class exceptions.FloatingPointError at 0xb7da3aac>, 'sum': <built-in function sum>, 'OverflowWarning': <class exceptions.OverflowWarning at 0xb7da3f8c>, 'getattr': <built-in function getattr>, 'abs': <built-in function abs>, 'exit': 'Use Ctrl-D (i.e. EOF) to exit.', 'True': True, 'FutureWarning': <class exceptions.FutureWarning at 0xb7dba02c>, 'None': None, 'hash': <built-in function hash>, 'len': <built-in function len>, 'credits':     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information., 'frozenset': <type 'frozenset'>, '__name__': '__builtin__', 'ord': <built-in function ord>, 'super': <type 'super'>, '_': None, 'TypeError': <class exceptions.TypeError at 0xb7da32fc>, 'license': Type license() to see the full license text, 'KeyboardInterrupt': <class exceptions.KeyboardInterrupt at 0xb7da338c>, 'UserWarning': <class exceptions.UserWarning at 0xb7da3e6c>, 'filter': <built-in function filter>, 'range': <built-in function range>, 'staticmethod': <type 'staticmethod'>, 'SystemError': <class exceptions.SystemError at 0xb7da3ddc>, 'pow': <built-in function pow>, 'RuntimeError': <class exceptions.RuntimeError at 0xb7da356c>, 'float': <type 'float'>, 'StopIteration': <class exceptions.StopIteration at 0xb7da329c>, 'globals': <built-in function globals>, 'divmod': <built-in function divmod>, 'enumerate': <type 'enumerate'>, 'apply': <built-in function apply>, 'LookupError': <class exceptions.LookupError at 0xb7da38cc>, 'open': <type 'file'>, 'quit': 'Use Ctrl-D (i.e. EOF) to exit.', 'basestring': <type 'basestring'>, 'UnicodeError': <class exceptions.UnicodeError at 0xb7da3b6c>, 'zip': <built-in function zip>, 'hex': <built-in function hex>, 'long': <type 'long'>, 'ReferenceError': <class exceptions.ReferenceError at 0xb7da3dac>, 'ImportError': <class exceptions.ImportError at 0xb7da33ec>, 'chr': <built-in function chr>, 'xrange': <type 'xrange'>, 'type': <type 'type'>, '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", 'Exception': <class exceptions.Exception at 0xb7da326c>, 'tuple': <type 'tuple'>, 'UnicodeTranslateError': <class exceptions.UnicodeTranslateError at 0xb7da3d4c>, 'reversed': <type 'reversed'>, 'UnicodeEncodeError': <class exceptions.UnicodeEncodeError at 0xb7da3bfc>, 'IOError': <class exceptions.IOError at 0xb7da347c>, 'hasattr': <built-in function hasattr>, 'delattr': <built-in function delattr>, 'setattr': <built-in function setattr>, 'raw_input': <built-in function raw_input>, 'SyntaxWarning': <class exceptions.SyntaxWarning at 0xb7da3f5c>, 'compile': <built-in function compile>, 'ArithmeticError': <class exceptions.ArithmeticError at 0xb7da398c>, 'str': <type 'str'>, 'property': <type 'property'>, 'MemoryError': <class exceptions.MemoryError at 0xb7da3e0c>, 'int': <type 'int'>, '__import__': <built-in function __import__>, 'KeyError': <class exceptions.KeyError at 0xb7da395c>, 'coerce': <built-in function coerce>, 'PendingDeprecationWarning': <class exceptions.PendingDeprecationWarning at 0xb7da3f2c>, 'file': <type 'file'>, 'EnvironmentError': <class exceptions.EnvironmentError at 0xb7da341c>, 'unichr': <built-in function unichr>, 'id': <built-in function id>, 'OSError': <class exceptions.OSError at 0xb7da34dc>, 'DeprecationWarning': <class exceptions.DeprecationWarning at 0xb7da3ecc>, 'min': <built-in function min>, 'execfile': <built-in function execfile>, 'complex': <type 'complex'>, 'bool': <type 'bool'>, 'ValueError': <class exceptions.ValueError at 0xb7da3b0c>, 'NotImplemented': NotImplemented, 'map': <built-in function map>, 'buffer': <type 'buffer'>, 'max': <built-in function max>, 'object': <type 'object'>, 'TabError': <class exceptions.TabError at 0xb7da383c>, 'callable': <built-in function callable>, 'ZeroDivisionError': <class exceptions.ZeroDivisionError at 0xb7da3a1c>, 'eval': <built-in function eval>, '__debug__': True, 'IndentationError': <class exceptions.IndentationError at 0xb7da380c>, 'AssertionError': <class exceptions.AssertionError at 0xb7da389c>, 'classmethod': <type 'classmethod'>, 'UnboundLocalError': <class exceptions.UnboundLocalError at 0xb7da36bc>, 'NotImplementedError': <class exceptions.NotImplementedError at 0xb7da35cc>, 'AttributeError': <class exceptions.AttributeError at 0xb7da374c>, 'OverflowError': <class exceptions.OverflowError at 0xb7da39bc>}}
>>> b
{'b': 4}

หลังจากอ่านที่คุณสุกรีอธิบายแล้ว ผมก็นั่ง key มั่วไปเรื่อยๆ
ไปสะดุดใจอยู่ตรงนี้อยู่ตั้งนาน

>>> a = {}
>>> exec "b=2" in a
>>> type(a['__builtins__'])
<type 'dict'>
>>> type(globals()['__builtins__'])
<type 'module'>

เราก็เห็นว่า builtins เหมือนกัน
ก็ควรจะเป็น object เดียวกันสิ
(ยิ่งเห็นว่า type(globals()) เป็น dict ด้วย)

งงอยู่นาน
สุดท้ายก็พอเชื่อมโยงได้

>>> id(a['__builtins__'])
-1210345708
>>> id(globals()['__builtins__'].__dict__)
-1210345708

อืมม์ เริ่มสนุกแล้ว(ถึงแม้จะไม่เข้าใจ)

sugree's picture

ผมใช้วิธีนี้สำหรับรับคำสั่งจากผู้ใช้เอามารันในตัวโปรแกรมตอน run-time จะได้จำกัดการเข้าถึงตัวแปรในโปรแกรมหลัก

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น