Python:将字符串转换为函数名;使用getattr还是等号?
我正在编辑一个叫做PROSS.py的文件,让它可以处理蛋白质结构的.cif文件。在这个PROSS.py文件里,有一些函数(我觉得这个名字没错,如果它不是属于某个类的话),这些函数就存在于这个.py文件里:
...
def unpack_pdb_line(line, ATOF=_atof, ATOI=_atoi, STRIP=string.strip):
...
...
def read_pdb(f, as_protein=0, as_rna=0, as_dna=0, all_models=0,
unpack=unpack_pdb_line, atom_build=atom_build):
我正在添加一个选项解析器,用来处理命令行参数,其中一个选项是指定除了unpack_pdb_line之外的其他方法。所以选项解析器中相关的部分是:
...
parser.add_option("--un", dest="unpack_method", default="unpack_pdb_line", type="string", help="Unpack method to use. Default is unpack_pdb_line.")
...
unpack=options.unpack_method
不过,options.unpack_method是一个字符串,我需要用这个字符串里面的名字来调用实际的函数。请问我该怎么用getattr等方法把这个字符串转换成实际的函数名呢?
谢谢,
保罗
5 个回答
3
vars()["unpack_pdb_line"]()
也可以这样使用。
或者
使用 globals()
或 locals()
也能以类似的方式工作。
>>> def a():return 1
>>>
>>> vars()["a"]
<function a at 0x009D1230>
>>>
>>> vars()["a"]()
1
>>> locals()["a"]()
1
>>> globals()["a"]()
1
谢谢!
4
如果你想利用Python已经为你准备好的字典(等等),我建议你可以这样做:
def str2fun(astr):
module, _, function = astr.rpartition('.')
if module:
__import__(module)
mod = sys.modules[module]
else:
mod = sys.modules['__main__'] # or whatever's the "default module"
return getattr(mod, function)
你可能想检查一下函数的签名(并捕获异常,以提供更友好的错误信息),比如通过使用inspect
模块,但这个方法是一个很实用的通用函数。如果某些已知函数的完整名称(包括模块或包的名称)写起来太麻烦,你可以很容易地添加一个快捷方式的字典,作为备用。
需要注意的是,我们不使用__import__
的结果(因为当函数在某个包的模块里时,它的工作方式不太对,__import__
返回的是包的顶层名称……直接在导入后访问sys.modules
会更实用)。
9
通常,你只需要用一个字典来存储 (函数名, 函数)
的配对:
unpack_options = { 'unpack_pdb_line' : unpack_pdb_line,
'some_other' : some_other_function }
unpack_function = unpack_options[options.unpack_method]