2016-07-15 2 views
2

파이썬 (2.7) eval을 (상대적으로) 안전한 방식으로 사용하려고합니다. 따라서, 나는 정의 :없음은 실제로 내장되어 있습니까?

예상대로
def safer_eval(string): 
    """Safer version of eval() as globals and builtins are inaccessible""" 
    return eval(string, {'__builtins__': {}}) 

는 다음이 더 이상 작동하지 않습니다

print safer_eval("None") 
None 
  • 그러나

    print safer_eval("True") 
    NameError: name 'True' is not defined 
    

    을, 난 여전히 "None" 문자열을 평가 후면 수 있습니다 그렇다면 None은 내장되어 있지 않습니까? 적어도 둘 다 __builtin__ ...

  • 왜 여전히 평가가 가능한가?

  • 내가해야한다면 어떻게 없앨 수 있을까요?
+4

'ast.literal_eval'을 사용하지 않는 이유는 무엇입니까? – jonrsharpe

+0

어떤 Python 버전입니까? – Ares

+0

예, '없음'은 내장 싱글 톤 객체이고 * 키워드 *입니다. –

답변

9

None 볼, 파이썬에서 일정Keywords documentation :

버전 2.4에서 변경 : None는 상수가되었고, 지금의 이름으로 컴파일러에 의해 인식되는 내장 된 객체 None. 키워드는 아니지만 다른 개체를 할당 할 수는 없습니다.

>>> from dis import dis 
>>> dis(compile('None', '', 'eval')) 
    1   0 LOAD_CONST    0 (None) 
       3 RETURN_VALUE 

TrueFalse들은 또한 마스크 할 수 있다는 뜻 파이썬 2에 내장 된 기능은 다음과 같습니다 당신이 그것을 이름을 할 때마다

는 컴파일러는 단순히 싱글 None 개체에 대한 참조를 삽입합니다.

파이썬 3, None, True에서

False 모두 now keywords 있으며, 세 가지 모두를 이름으로 단지 구체화됩니다

>>> eval('True', {'__builtins__': {}}) 
True 

Guido van Rossum's blog post on why this was changed를 참조하십시오.

>>> s = ''' 
... [ 
...  c for c in().__class__.__base__.__subclasses__() 
...  if c.__name__ == 'catch_warnings' 
... ][0]()._module.__builtins__ 
... ''' 
>>> eval(s, {'__builtins__': {}}) 
{'bytearray': <type 'bytearray'>, 'IndexError': <type 'exceptions.IndexError'>, 'all': <built-in function all>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <type 'exceptions.SyntaxError'>, 'unicode': <type 'unicode'>, 'UnicodeDecodeError': <type 'exceptions.UnicodeDecodeError'>, 'memoryview': <type 'memoryview'>, 'isinstance': <built-in function isinstance>, 'copyright': Copyright (c) 2001-2015 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': <type 'exceptions.NameError'>, 'BytesWarning': <type 'exceptions.BytesWarning'>, 'dict': <type 'dict'>, 'input': <built-in function input>, 'oct': <built-in function oct>, 'bin': <built-in function bin>, 'SystemExit': <type 'exceptions.SystemExit'>, 'StandardError': <type 'exceptions.StandardError'>, 'format': <built-in function format>, 'repr': <built-in function repr>, 'sorted': <built-in function sorted>, 'False': False, 'RuntimeWarning': <type 'exceptions.RuntimeWarning'>, 'list': <type 'list'>, 'iter': <built-in function iter>, 'reload': <built-in function reload>, 'Warning': <type 'exceptions.Warning'>, '__package__': None, 'round': <built-in function round>, 'dir': <built-in function dir>, 'cmp': <built-in function cmp>, 'set': <type 'set'>, 'bytes': <type 'str'>, 'reduce': <built-in function reduce>, 'intern': <built-in function intern>, 'issubclass': <built-in function issubclass>, 'Ellipsis': Ellipsis, 'EOFError': <type 'exceptions.EOFError'>, 'locals': <built-in function locals>, 'BufferError': <type 'exceptions.BufferError'>, 'slice': <type 'slice'>, 'FloatingPointError': <type 'exceptions.FloatingPointError'>, 'sum': <built-in function sum>, 'getattr': <built-in function getattr>, 'abs': <built-in function abs>, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'print': <built-in function print>, 'True': True, 'FutureWarning': <type 'exceptions.FutureWarning'>, 'ImportWarning': <type 'exceptions.ImportWarning'>, 'None': None, 'hash': <built-in function hash>, 'ReferenceError': <type 'exceptions.ReferenceError'>, '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': <type 'exceptions.TypeError'>, 'license': See http://www.python.org/2.7/license.html, 'KeyboardInterrupt': <type 'exceptions.KeyboardInterrupt'>, 'UserWarning': <type 'exceptions.UserWarning'>, 'filter': <built-in function filter>, 'range': <built-in function range>, 'staticmethod': <type 'staticmethod'>, 'SystemError': <type 'exceptions.SystemError'>, 'BaseException': <type 'exceptions.BaseException'>, 'pow': <built-in function pow>, 'RuntimeError': <type 'exceptions.RuntimeError'>, 'float': <type 'float'>, 'MemoryError': <type 'exceptions.MemoryError'>, 'StopIteration': <type 'exceptions.StopIteration'>, 'globals': <built-in function globals>, 'divmod': <built-in function divmod>, 'enumerate': <type 'enumerate'>, 'apply': <built-in function apply>, 'LookupError': <type 'exceptions.LookupError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'basestring': <type 'basestring'>, 'UnicodeError': <type 'exceptions.UnicodeError'>, 'zip': <built-in function zip>, 'hex': <built-in function hex>, 'long': <type 'long'>, 'next': <built-in function next>, 'ImportError': <type 'exceptions.ImportError'>, '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': <type 'exceptions.Exception'>, 'tuple': <type 'tuple'>, 'UnicodeTranslateError': <type 'exceptions.UnicodeTranslateError'>, 'reversed': <type 'reversed'>, 'UnicodeEncodeError': <type 'exceptions.UnicodeEncodeError'>, 'IOError': <type 'exceptions.IOError'>, 'hasattr': <built-in function hasattr>, 'delattr': <built-in function delattr>, 'setattr': <built-in function setattr>, 'raw_input': <built-in function raw_input>, 'SyntaxWarning': <type 'exceptions.SyntaxWarning'>, 'compile': <built-in function compile>, 'ArithmeticError': <type 'exceptions.ArithmeticError'>, 'str': <type 'str'>, 'property': <type 'property'>, 'GeneratorExit': <type 'exceptions.GeneratorExit'>, 'int': <type 'int'>, '__import__': <built-in function __import__>, 'KeyError': <type 'exceptions.KeyError'>, 'coerce': <built-in function coerce>, 'PendingDeprecationWarning': <type 'exceptions.PendingDeprecationWarning'>, 'file': <type 'file'>, 'EnvironmentError': <type 'exceptions.EnvironmentError'>, 'unichr': <built-in function unichr>, 'id': <built-in function id>, 'OSError': <type 'exceptions.OSError'>, 'DeprecationWarning': <type 'exceptions.DeprecationWarning'>, 'min': <built-in function min>, 'UnicodeWarning': <type 'exceptions.UnicodeWarning'>, 'execfile': <built-in function execfile>, 'any': <built-in function any>, 'complex': <type 'complex'>, 'bool': <type 'bool'>, 'ValueError': <type 'exceptions.ValueError'>, 'NotImplemented': NotImplemented, 'map': <built-in function map>, 'buffer': <type 'buffer'>, 'max': <built-in function max>, 'object': <type 'object'>, 'TabError': <type 'exceptions.TabError'>, 'callable': <built-in function callable>, 'ZeroDivisionError': <type 'exceptions.ZeroDivisionError'>, 'eval': <built-in function eval>, '__debug__': True, 'IndentationError': <type 'exceptions.IndentationError'>, 'AssertionError': <type 'exceptions.AssertionError'>, 'classmethod': <type 'classmethod'>, 'UnboundLocalError': <type 'exceptions.UnboundLocalError'>, 'NotImplementedError': <type 'exceptions.NotImplementedError'>, 'AttributeError': <type 'exceptions.AttributeError'>, 'OverflowError': <type 'exceptions.OverflowError'>} 

또는 당신은 단순히 깨진 코드를 작성하여 인터프리터를 날려 버릴 수가 여전히 다른 수단을 통해 참조 할 수있는, 심지어 __builtins__이 거세으로, 평가에 대한 아무것도 안전이 있음을

주 목적. Eval really is dangerous을 참조하십시오.

파이썬 리터럴 구문 (목록, 튜플, 사전, 문자열, 숫자 등)을로드하고 싶다면 안전하도록 특별히 설계된 ast.literal_eval() function을 사용하고 싶습니다.

+0

아마도 'ast.literal_eval'에 대해 언급하고 그 질문에 대한 링크를 원할 것입니다 : http://stackoverflow.com/questions/4710247/python-3-are-there-any-known-security-holes-in-ast-literal -evalnode-or-string? 가능성이있는 후속 질문 인 것 같습니다 ... – NichtJens

+0

@NichtJens : 언급을 추가했습니다. 그 질문은 연결이 필요하다고 생각하지 않습니다. 문서로 충분합니다 : * 안전하게 평가하십시오 ... * –

+0

예, 좋습니다! 실제로 여기에있는 후속 질문에 실제로 응답하고 있습니다 ;-) – NichtJens

1

이것은 Python 2.7에서 완벽하게 유효한 문입니다.

True = False 
>>> print True 
False 

봅니다 종류의 당신의 머리 회전을 만들 수 있습니다 ..

SyntaxError: cannot assign to None

하지만 None 함께 수행하고 있습니다. 확실하지는 않지만, True이 내장되어 있으며 None은 실제로 상수 인입니다. True을 다른 값으로 변경할 수 있지만 None은 변경할 수 없습니다.

+0

아니요, True 및 False가 내장되어 있으며 마스크 처리가 가능합니다. –

+0

그래서 그들은 모두 내장되어 있습니까? 그 때의 차이점은 무엇입니까? 편집 : 아, 알 겠어, '없음'도 키워드입니다. – Ares

+0

기술적으로는 (적어도 python2.x에는 없지만) 키워드라는 것이 확실하지 않습니다 :'import keyword; print keyword.iskeyword ('None')' – mgilson

관련 문제