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):
我正在为命令行参数添加一个 optons 解析器,以及一个选项之一是指定除 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 是一个字符串,我需要使用与 options.unpack_method 中的字符串同名的函数。如何使用 getattr 等将字符串转换为实际的函数名称?
谢谢,
保罗
I am editing PROSS.py to work with .cif files for protein structures. Inside the existing PROSS.py, there is the following functions (I believe that's the correct name if it's not associated with any class?), just existing within the .py file:
...
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):
I am adding an optons parser for command line arguments, and one of the options is to specify an alternate method to use besides unpack_pdb_line. So the pertinent part of the options parser is:
...
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
However, options.unpack_method is a string and I need to use the function with the same name as the string inside options.unpack_method. How do I use getattr etc to convert the string into the actual function name?
Thanks,
Paul
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常,您只需使用字典并存储
(func_name, function)
对:Usually you just use a dict and store
(func_name, function)
pairs:如果你想利用 Python 已经为你保存的字典 (&c),我建议:
你可能需要检查函数的签名(并捕获异常以提供更好的错误消息),例如通过
检查,但这是一个有用的通用功能。
如果某些已知函数的完整字符串名称(包括模块/包限定)难以以这种方式表达,则可以轻松添加快捷方式字典作为后备。
请注意,我们不使用
__import__
的结果(当函数位于某个包内的模块中时,它无法正常工作,因为__import__
返回顶级名称包的...导入后访问 sys.modules 更实用)。If you want to exploit the dictionaries (&c) that Python's already keeping on your behalf, I'd suggest:
You'll probably want to check the function's signature (and catch exceptions to provide nicer error messages) e.g. via
inspect
, but this is a useful general-purpose function.It's easy to add a dictionary of shortcuts, as a fallback, if some known functions full string names (including module/package qualifications) are unwieldy to express this way.
Note we don't use
__import__
's result (it doesn't work right when the function is in a module inside some package, as__import__
returns the top-level name of the package... just accessingsys.modules
after the import is more practical).vars()["unpack_pdb_line"]()
也可以工作。或者
globals() 或 locals() 也将以类似的方式工作。
干杯,
vars()["unpack_pdb_line"]()
will work too.or
globals() or locals() will also work similar way.
Cheers,
如果您正在获取用户的输入,为了安全起见,最好是
使用手工制作的字典,它只接受一组明确定义的可接受的用户输入:
暂时忽略安全性,让我们顺便注意一下,这是一种简单的方法
从(变量名字符串)到(变量名引用的值)
是使用 globals() 内置字典:
当然,只有当变量
unpack_pdb_line
位于全局命名空间中时,这才有效。如果您需要访问 packgae 中的模块或模块中的变量,那么
你可以使用这个函数
你可以像这样使用它:
它适用于嵌套包、模块、函数或(全局)变量。
If you are taking input from a user, for the sake of security it is probably best to
use a hand-made dict which will accept only a well-defined set of admissible user inputs:
Ignoring security for a moment, let us note in passing that an easy way to
go from (strings of variable names) to (the value referenced by the variable name)
is to use the globals() builtin dict:
Of course, that will only work if the variable
unpack_pdb_line
is in the global namespace.If you need to reach into a packgae for a module, or a module for a variable, then
you could use this function
You could use it like this:
It works for nested packages, modules, functions, or (global) variables.
其中
eval_dottedname()
:eval_dottedname()
是所有答案中唯一一个支持其中包含多个点的任意名称的答案,例如“datetime.datetime.now”。虽然它不适用于需要导入的嵌套模块,但我什至不记得 stdlib 中此类模块的示例。Where
eval_dottedname()
:eval_dottedname()
is the only one among all answers that supports arbitrary names with multiple dots in them e.g., `'datetime.datetime.now'. Though it doesn't work for nested modules that require import, but I can't even remember an example from stdlib for such module.