【问题标题】:Get all the class types referenced within a function or class获取函数或类中引用的所有类类型
【发布时间】:2020-11-10 22:07:29
【问题描述】:

我正在开发一个代码分析器,我正在尝试识别 Python 中的函数或类中引用的所有类类型。

例如说我有这个类:

import collections

Bar = collections.namedtuple('Bar', ['bar'])
Baz = collections.namedtuple('Baz', ['baz'])

class Foo(object):
    def get_bar(self):
        return Bar(1)
    def get_baz(self):
        return Baz(2)

我正在寻找一种方法来获取函数和类的类型。像这样的:

print(get_types(Foo.get_bar)) # ['Bar']
print(get_types(Foo.get_baz)) # ['Baz']
print(get_types(Foo)) # ['Bar','Baz']

【问题讨论】:

  • 有趣,我怀疑inspect 中有一个方法可以帮助实现这一目标
  • This answer 看起来可能有助于解决您的问题。
  • 您是否在寻找类型注释?注意return Bar(1) 是否返回Bar、其他类型、随机类型或因异常而爆炸无法仅从该源代码中得知。您愿意对您的代码做出哪些假设?
  • @MisterMiyagi 类型注释可以工作,但需要我们通过许多没有它们的旧代码重新添加它们。这是一个潜在的解决途径。我真正要寻找的是每个函数中的所有 ORM 类型(我们使用 Peewee),因此我们可以确定哪些函数涉及哪些 DB 表。函数的执行对此并不重要,只要源在其逻辑的任何分支中包含该类型即可。

标签: python python-3.x introspection


【解决方案1】:

一种解决方案可能涉及使用类型注释。设置get_bar()的返回值为Barget_baz()的返回值为Baz,可以写成get_types()如下...

import inspect
import collections

Bar = collections.namedtuple('Bar', ['bar'])
Baz = collections.namedtuple('Baz', ['baz'])


class Foo(object):
    def get_bar(self) -> Bar:
        return Bar(1)
    def get_baz(self) -> Baz:
        return Baz(2)


def get_types(obj):
    if inspect.isclass(obj):
        methods = [method for method in dir(obj)
                   if callable(getattr(obj, method)) and not method.startswith('_')]
        return [get_types(getattr(obj, method)) for method in methods]

    if callable(obj):
        return [obj.__annotations__['return'].__name__]


def main():
    print(get_types(Foo.get_bar)) # ['Bar']
    print(get_types(Foo.get_baz)) # ['Baz']
    print(get_types(Foo)) # ['Bar','Baz']


if __name__ == '__main__':
    main()

get_types(obj) 中,如果obj 包含一个类的实例,您可以选择该类的非私有方法并在每个方法上返回get_types()。如果obj 包含一个函数,那么我们只返回该函数的return 属性。

【讨论】:

  • 一些正在分析的代码具有我们在 mypy 中使用的类型注释,但有很多遗留代码没有。这看起来很有希望,但它需要我们回顾所有代码并填写所有注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 2020-05-24
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
相关资源
最近更新 更多