【问题标题】:How to check currently valid types in Python如何在 Python 中检查当前有效的类型
【发布时间】:2012-08-02 03:34:00
【问题描述】:

背景: 使用 numpy/scipy 从 R 迁移到 Python。尝试制作一些有用功能的小模块。特别是,我正在尝试创建一个递归元素类型检查器。

问题: 是否可以在 Python 环境中获取正在调用函数的当前有效类型的列表?

例如,isinstance(1,int) 将返回 Trueisinstance(1,str) 将返回 False,但 isinstance(1,asdf) 将抛出 NameError: name 'asdf' is not defined,即定义了 int 和 str,但未定义 asdf。如何获取已定义的类型列表或当前 Python 环境中存在的名称,并按类型过滤它们?

【问题讨论】:

  • 不相关,但这有点违背 Python 的鸭子类型。
  • 您实际上想要做什么?是的,我读过recursive element type checker

标签: python typechecking


【解决方案1】:

在 Python 中,类型本身就是普通对象。也就是说,例如,

type('hello') == str
type(5) == int
type(int) == type
type(type) == type

都是True

为此,请查找范围内指向type 类型对象的所有变量。

To get all objects in scope,查看 dir()(不包括像 int 这样的内置名称)和 dir(__builtins__)(内置名称) locals()(在当前函数)、globals()(在当前模块中的函数之外定义的变量)和vars(__builtins__)(内置名称)。这些都是来自 name => object 的字典,因此将它们全部组合并获取对象:

objs = dict(vars(__builtins__), **dict(globals(), **locals())).values()

并且只过滤类型:

types_in_scope = [o for o in objs if isinstance(o, type)]

请注意,这些只是范围内指向类型的变量。很有可能引用一个类型未分配给范围内任何变量的对象。例如:

def foo():
    class Foo:
        pass
    return Foo()
x = foo()

【讨论】:

  • 谢谢,但似乎不起作用:/ print [type(o) for o in objs] 返回所有类型 str。因此 types_in_scope 返回为空
  • @whearyou:哎呀。我忘了dict() 只返回名称,而不是实际对象。已在编辑中修复。
  • 谢谢,但stackoverflow.com/a/39858/1077083 显然是个坏主意,并且不适用于 Python 3 或 JPython 或非 2.x CPython。相反,我做了 objs = builtins.__dict__ objs.update(globals()) objs.update(locals()) 它有效!所以谢谢!我提出了检查 :) 虽然你会想要为未来的用户编辑你的答案......
  • @whearyou:仅当键不是字符串时。但是这里的键保证是字符串,因为它们是变量名。
【解决方案2】:

也许您可以查找types 模块?请在此处查看文档:http://docs.python.org/library/types.html。你也可以在你的程序中获取当前的变量,像这样:

In [9]: def spam():
            x=5
            y=6

In [10]: spam.func_code.co_varnames
Out[10]: ('x', 'y')

希望对您有所帮助,您可以开始使用。抱歉,如果我完全偏离了轨道。

【讨论】:

  • 我会为 types 模块 +1,但不知道你为什么包含 hacky 代码来获取变量名,这不是问题的一部分。
  • Op:“我怎样才能获得已定义的类型列表,或当前python环境中存在的名称”..我认为这可能有助于OP获得当前python中的名称列表环境。
  • 当前环境中的名称将是 locals()globals()
  • @Amit "从 Python 2.2 开始,内置工厂函数如 int() 和 str() 也是对应类型的名称。现在这是访问类型的首选方式,而不是使用类型模块。”
  • @ jamylak locals() 和 globals() 似乎没有返回所有名称,因为它不返回 int 或 str
猜你喜欢
  • 2013-05-13
  • 1970-01-01
  • 2018-06-16
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 2013-07-10
相关资源
最近更新 更多