Python 试行字符串表明式函数(eval exec execfile),evalexecfile

精心研读后学习了八个函数:
eval:计算字符串中的表明式
exec:奉行字符串中的语句
execfile:用来施行二个文本

Python 实施字符串说明式函数(eval exec execfile),evalexecfile

精心研读后学习了多少个函数:
eval:总计字符串中的表达式
exec:施行字符串中的语句
execfile:用来试行一个文书

需注意的是,exec是八个言辞,而eval()和execfile()则是内建built-in函数。

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> x=1
>>> print eval("x+1")
2
>>> exec "print 'http://blog.leniy.org/python-eval-exec-execfile.html'"
http://blog.leniy.org/python-eval-exec-execfile.html
>>> 

再者,大家有的时候候利用input输入一些数据,举例

>>> input("请输入:")
请输入:1+2**3
9
>>> 

实则这里的input也是eval的利用,等效于

>>> eval(raw_input("请输入:"))
请输入:1+2**3
9
>>> 

eval()、exec()与execfile(),evalexecexecfile

eval(expression[, globals[, locals]])

eval()函数实行叁个python表明式字符串并回到表明式施行后的结果:

>>> x = 1
>>> eval('x + 1')
2

expression参数为一个表明式字符串,globalslocals为可选的参数,globals非得是叁个字典对象,locals可为放肆映射对象,分别作为代码施行的大局和有个别命名空间。

globalslocals参数缺点和失误的时候,表达式会采纳当前条件的大局和部分命名空间值:

>>> x = 1
>>> g = {'x' : 2}
>>> eval('x + 1', g)
3
>>> eval('x + 1')
2

eval()函数在数据类型调换中很有用,能够将字符串转换到字典、列表等:

>>> exp = '[1,2,3,4]'
>>> eval(exp)
[1, 2, 3, 4]
>>> exp = '{"a" : 1}'
>>> eval(exp)
{'a': 1}

eval()也得以应用模块:

>>> import os
>>> eval('os.getcwd()')
'/home/user'

当然,eval不能够直接对模块实行操作,如果非要使用eval实行import:

>>> eval('__import__("os").getcwd()')
'/home/user'

那貌似用于依照客户供给动态的调用分裂的模块。

别的的用做计算器啥的也可想而知,可是eval函数也无法滥用,比如要收获用户的输入并求值eval(raw_input()),

这种景况下,用户输入open(__file__).read()可直接把原作件读出来了。

要安全的行使eval()函数,能够选拔globals和locals多个参数来安装白名单,当参数缺点和失误的时候,表明式会使用当前条件的大局和部分命名空间值,即globals()和locals()中含有的模块和函数:

>>> import os
>>> 'os' in globals()
True
>>> eval('os.getcwd()')
'/home/user'

将globals和locals七个参数设置为空:

>>> import os
>>> eval('os.getcwd()', {}, {})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'os' is not defined

但使用内置函数却足以绕过白名单:

>>> eval('abs(10)', {}, {})
10
>>> eval('__import__("os").getcwd()', {}, {})
'/home/user'

能够看下globals():

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

__builtins__安装着python的松开函数,下边包车型客车写法是同一的:

>>> abs(10)
10
>>> __builtins__.abs(10)
10

将__builtins__安装为空则可制止内置函数的滥用:

>>> eval('abs(10)', {'__builtins__' : None}, {})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'abs' is not defined 

 看状态那下是平安了,可是照旧得以绕过的:

>>> ().__class__.__bases__[0].__subclasses__()
[<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, <type 'member_descriptor'>, <type 'file'>, <type 'PyCapsule'>, <type 'cell'>, <type 'callable-iterator'>, <type 'iterator'>, <type 'sys.long_info'>, <type 'sys.float_info'>, <type 'EncodingMap'>, <type 'fieldnameiterator'>, <type 'formatteriterator'>, <type 'sys.version_info'>, <type 'sys.flags'>, <type 'sys.getwindowsversion'>, <type 'exceptions.BaseException'>, <type 'module'>, <type 'imp.NullImporter'>, <type 'zipimport.zipimporter'>, <type 'nt.stat_result'>, <type 'nt.statvfs_result'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class '_abcoll.Hashable'>, <type 'classmethod'>, <class '_abcoll.Iterable'>, <class '_abcoll.Sized'>, <class '_abcoll.Container'>, <class '_abcoll.Callable'>, <class 'site._Printer'>, <class 'site._Helper'>, <type '_sre.SRE_Pattern'>, <type '_sre.SRE_Match'>, <type '_sre.SRE_Scanner'>, <class 'site.Quitter'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <type 'operator.itemgetter'>, <type 'operator.attrgetter'>, <type 'operator.methodcaller'>, <type 'functools.partial'>, <type 'MultibyteCodec'>, <type 'MultibyteIncrementalEncoder'>, <type 'MultibyteIncrementalDecoder'>, <type 'MultibyteStreamReader'>, <type 'MultibyteStreamWriter'>, <type 'time.struct_time'>, <type '_ssl._SSLContext'>, <type '_ssl._SSLSocket'>, <type 'cStringIO.StringO'>, <type 'cStringIO.StringI'>, <class 'socket._closedsocket'>, <type '_socket.socket'>, <type 'method_descriptor'>, <class 'socket._socketobject'>, <class 'socket._fileobject'>, <type '_thread._localdummy'>, <type 'thread._local'>, <type 'thread.lock'>, <type 'collections.deque'>, <type 'deque_iterator'>, <type 'deque_reverse_iterator'>, <type 'itertools.combinations'>, <type 'itertools.combinations_with_replacement'>, <type 'itertools.cycle'>, <type 'itertools.dropwhile'>, <type 'itertools.takewhile'>, <type 'itertools.islice'>, <type 'itertools.starmap'>, <type 'itertools.imap'>, <type 'itertools.chain'>, <type 'itertools.compress'>, <type 'itertools.ifilter'>, <type 'itertools.ifilterfalse'>, <type 'itertools.count'>, <type 'itertools.izip'>, <type 'itertools.izip_longest'>, <type 'itertools.permutations'>, <type 'itertools.product'>, <type 'itertools.repeat'>, <type 'itertools.groupby'>, <type 'itertools.tee_dataobject'>, <type 'itertools.tee'>, <type 'itertools._grouper'>, <class 'threading._Verbose'>, <class 'string.Template'>, <class 'string.Formatter'>, <type 'CArgObject'>, <type '_ctypes.CThunkObject'>, <type '_ctypes._CData'>, <type '_ctypes.CField'>, <type '_ctypes.DictRemover'>, <type 'Struct'>, <class 'ctypes.CDLL'>, <class 'ctypes.LibraryLoader'>, <type 'cPickle.Unpickler'>, <type 'cPickle.Pickler'>, <class 'idlelib.rpc.SocketIO'>, <class 'idlelib.rpc.RemoteObject'>, <class 'idlelib.rpc.RemoteProxy'>, <class 'idlelib.rpc.RPCProxy'>, <class 'idlelib.rpc.MethodProxy'>, <type '_io._IOBase'>, <type '_io.IncrementalNewlineDecoder'>, <class 'subprocess.Popen'>, <class 'webbrowser.BaseBrowser'>, <class 'idlelib.tabbedpages.Page'>, <class 'idlelib.EditorWindow.HelpDialog'>, <type '_hashlib.HASH'>, <type '_random.Random'>, <class 'idlelib.EditorWindow.EditorWindow'>, <class 'idlelib.EditorWindow.IndentSearcher'>, <class 'idlelib.run.Executive'>]

透过tuple的class找到它的基类,相当于object,然后再找到object的种种子类,从中能够观望许多模块。

利用Quitter退出解释器:

>>> eval("[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__== 'Quitter'][0](0)()", {'__builtins__':None})
user:~$ 

configobj,urllib,urllib2,setuptools等模块中都有os模块的嵌入:

>>> import configobj
>>> 'os' in configobj.__dict__
True
>>> import urllib2
>>> 'os' in urllib2.__dict__
True
>>> import setuptools
>>> 'os' in setuptools.__dict__
True

使用zipimport通过egg文件导入这几个模块就足以应用os模块了:

eval("[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == 'zipimporter'][0]('/path/to/configobj-5.0.5-py2.7.egg').load_module('configobj').os.getcwd()", {'__builtins__':None})

上述可以看看,eval()函数的纰漏如故广大的,要是只是用来做类型调换,可以动用ast.literal_eval
代替eval:

>>> import ast
>>> ast.literal_eval('[1, 2, 3]')
[1, 2, 3]
>>> ast.literal_eval('abs(10)')

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    ast.literal_eval('abs(10)')
  File "C:\Python27\lib\ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "C:\Python27\lib\ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string
>>> eval('abs(10)')
10

 exec(str [, globals[, locals]])

 execfile(filename [, globals[, locals]])

看似的,exec函数实行二个分包python代码的字符串,execfile则施行三个文件,后七个参数与eval类似。

>>> a = [1, 2, 3, 4]
>>> exec('for i in a: print i')

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

给eval或许exec函数字传送递字符串时,深入分析器首先会把字符串编写翻译成字节码,为防止消耗财富,能够使用compile函数将字符串预编写翻译:

compile(str, filename, kind)

str是要预编写翻译的字符串,filename为字符串所在的文书,kind参数为single时表示一条语句,exec代表一组语句,eval代表一个表明式

>>> s = 'for i in [1, 2, 3]: print i'
>>> c = compile(s, '', 'exec')
>>> exec(c)
1
2
3
>>> s2 = '1+1'
>>> c2 = compile(s2, '', 'eval')
>>> eval(c2)
2

eval奉行exec类型的预编写翻译字节码时,会回来None:

>>> s2 = '1+1'
>>> c2 = compile(s2, '', 'exec')
>>> print eval(c2)
None

 从前见到过三个案例,使用eval转换不法规的json数据:

>>> blog = "{url : 'www.example.com'}"

地点url贫乏引号,使用eval和json.loads()均会报错。

>>> eval(blog)
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    eval(blog)
  File "<string>", line 1, in <module>
NameError: name 'url' is not defined

采纳eval时,eval会将url视为变量名并总括在globals和locals中搜索url的值,增多一下globals参数:

>>> eval(blog, {'url' : 'url'})
{'url': 'www.example.com'}

据此,未来要做的是正是建设构造八个类dict的投射对象,其中value的值须要与key值同样,可以利用type函数来确立:

>>> ValueFromKey = type('ValueFromKey', (dict,), dict(__getitem__ = lambda self,k : k))
>>> eval(blog, ValueFromKey())
{'url': 'www.example.com'}

在新建的type对象基类元祖中满含下dict,然后在对象的dict中定义一下__getitem__措施,使value值与key值一致就可以。

eval
( expression [, globals [, locals ]])
eval()函数推行一个python表明式字符串并赶回表明式试行后的结果:
x…

需注意的是,exec是二个话语,而eval()和execfile()则是内建built-in函数。

python当中的eval()函数是起什作业的?

eval参数是三个字符串, 能够把这一个字符串当成说明式来求值,

比如’x+1’便是贰个表明式字符串
>>> x = 1
>>> print eval(‘x+1’)
2
 

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> x=1
>>> print eval("x+1")
2
>>> exec "print 'http://blog.leniy.org/python-eval-exec-execfile.html'"
http://blog.leniy.org/python-eval-exec-execfile.html
>>> 

python内建函数

自个儿也在学python,一同研讨探讨?金沙js333娱乐场,
 

推行字符串表明式函数(eval exec
execfile),evalexecfile 留神研读后学习了多个函数:
eval:计算字符串中的表达式 exec:实践字符串中的语句…

发表评论

电子邮件地址不会被公开。 必填项已用*标注