在 Python 中通过名称作为字符串调用类型
我知道使用 globals()、locals() 和 getattr 通过字符串引用 Python 中的事物(如 这个问题),但除非我遗漏了一些明显的东西,否则我似乎无法将其与调用类型一起使用。
例如:
In [12]: locals()['int']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
e:\downloads_to_access\<ipython console> in <module>()
KeyError: 'int'
In [13]: globals()['int']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
e:\downloads_to_access\<ipython console> in <module>()
KeyError: 'int'
getattr(???, 'int')...
这样做的最佳方法是什么?
I'm aware of using globals(), locals() and getattr to referance things in Python by string (as in this question) but unless I'm missing something obvious I can't seem to use this with calling types.
e.g.:
In [12]: locals()['int']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
e:\downloads_to_access\<ipython console> in <module>()
KeyError: 'int'
In [13]: globals()['int']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
e:\downloads_to_access\<ipython console> in <module>()
KeyError: 'int'
getattr(???, 'int')...
What's the best way of doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
有本地变量、全局变量,然后是内置变量。
也许您正在寻找内置的:
There are locals,globals, and then builtins.
Perhaps you are looking for the builtin:
您已经获得了使用内置函数的解决方案,但工具包中另一个值得保留的技术是调度表。如果您的 CSV 设计为供以多种语言编写的多个应用程序使用,则它可能如下所示:
在这种情况下,您可能需要类似这样的内容,其中
csv
是包含数据的元组列表上图:这使您可以灵活地允许任意字符串映射到有用的类型。您不必修改数据即可获得 python 期望的准确值。
You've already gotten a solution using builtins, but another worthwhile technique to hold in your toolbag is a dispatch table. If your CSV is designed to be used by multiple applications written in multiple languages, it might look like this:
In such a case you might want something like this, where
csv
is a list of tuples containing the data above:That gives you the flexibility of allowing arbitrary strings to map to useful types. You don't have to massage your data to give you the exact values python expects.
这里的问题是 int 是 __builtins__ 模块的一部分,而不仅仅是全局命名空间的一部分。您可以使用以下代码获取内置类型,例如
int
:同样,您可以通过将模块名称作为字符串索引传递给
globals()
,然后使用getattr
提取所需的属性。The issue here is that
int
is part of the__builtins__
module, not just part of the global namespace. You can get a built-in type, such asint
, using the following bit of code:Similarly, you can access any other (imported) module by passing the module's name as a string index to
globals()
, and then usinggetattr
to extract the desired attributes.评论表明您对使用 eval 生成数据的想法不满意。在
__builtins__
中查找函数可以让您找到eval
。给出的最基本的解决方案如下所示:
您可以像这样使用它:
很酷。工作得很好。不过这个怎么样?
这符合你的预期吗?除非您明确希望这样做,否则您需要采取一些措施来防止不可信的输入在您的命名空间中出现。我强烈推荐一个简单的白名单,在无效输入的情况下优雅地引发某种异常,如下所示:
但如果你无法忍受,你仍然可以通过验证请求的功能来添加一点盔甲实际上是一种类型:
Comments suggest that you are unhappy with the idea of using eval to generate data. looking for a function in
__builtins__
allows you to findeval
.the most basic solution given looks like this:
You would use it like so:
cool. works pretty ok. how about this one though?
does this do what you expect? Unless you explicitly want this, you need to do something to prevent untrustworthy inputs from poking about in your namespace. I'd strongly recommend a simple whitelist, gracefully raising some sort of exception in the case of invalid input, like so:
but if you just can't bear that, you can still add just a bit of armor by verifying that the requested function is actually a type:
如果你有一个字符串,它是一个事物的名称,并且你想要这个事物,你也可以使用:
不过请记住,这非常强大,你需要了解事物可能包含什么以及它来自哪里。例如,如果您接受用户输入作为事物,则恶意用户可以使用此代码对您的计算机造成无限的损害。
If you have a string that is the name of a thing, and you want the thing, you can also use:
Keep in mind though, that this is very powerful, and you need to understand what thing might contain, and where it came from. For example, if you accept user input as thing, a malicious user could do unlimited damage to your machine with this code.