简体   繁体   English

如何通过通用的 pythonic 方法获取 class 实例属性的列表?

[英]How to get a list of class instance attributes via a generic pythonic approach?

The goal is to retrieve a list of class instance attributes.目标是检索 class 个实例属性的列表。 Perferably would like to find some way to do this without having to instantiate an instance of the class (some kind of pre-instantiation inspection). Perperably 希望找到某种方法来执行此操作,而不必实例化 class 的实例(某种预实例化检查)。 However, this may not be possible.然而,这可能是不可能的。 Alternatively, what would be the most pythonic way to do this, given the need to apply it to generic classes.或者,考虑到需要将其应用于泛型类,什么是最 pythonic 的方式来做到这一点。

Here is what I have put together so far and an example of the hurdles to get past to achieve the goal:以下是我到目前为止整理的内容以及为实现目标而需要克服的障碍的示例:

First, a basic class and a function that instantiates a class instance, inspects it and returns the attribues successfully:首先,一个基本的 class 和一个 function 实例化一个 class 实例,检查它并成功返回属性:

from typing import List
import inspect
import datetime as dt

class Apple:

    def __init__(self,color:str,size:int) -> None:

        self.log_time = dt.datetime.now()
        self.color = color
        self.size = size

def get_attributes(class_obj:object) -> List[str]:

    '''Returns instantiated class attributes.'''

    params = list(inspect.signature(class_obj).parameters.keys())
    kwargs = {param:None for param in params}
    instance = class_obj(**kwargs)
    attributes = list(vars(instance))

    return attributes

get_attributes(Apple)

>>>

['log_time', 'color', 'size']

This works fine since there are no issues generating attributes (with None populating the parameters) in the init method.这工作正常,因为在init方法中没有生成属性(使用 None 填充参数)的问题。

However, for another class:但是,对于另一个 class:

class Orange:

    def __init__(self,color:str,size:int) -> None:

        self.log_time = dt.datetime.now()
        self.color = color
        self.size = size
        self.another_attribute = size * 2

get_attributes(Orange)

>>>

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[63], line 1
----> 1 get_attributes(Orange)

Cell In[60], line 7, in get_attributes(class_obj)
      5 params = list(inspect.signature(class_obj).parameters.keys())
      6 kwargs = {param:None for param in params}
----> 7 instance = class_obj(**kwargs)
      8 attributes = list(vars(instance))
     10 return attributes

Cell In[62], line 8, in Orange.__init__(self, color, size)
      6 self.color = color
      7 self.size = size
----> 8 self.another_attribute = size * 2

TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'

The deployment of None creates the issue. None 的部署会产生问题。 Entering specific dummy parameters that explicitly permit the class to generate is not the route that I want to take, since this is not a generic enough solution.输入明确允许 class 生成的特定虚拟参数不是我想要采用的路线,因为这不是一个足够通用的解决方案。

Looking for solutions as to how to achieve the goal generically and in the most pythonic manner.寻找关于如何以最 pythonic 方式一般地实现目标的解决方案。

Thanks!谢谢!

Knowing that general class instance can be dynamically assigned with a new attributes during its life cycle we shouldn't chase an instantiated object with inspect to get its original state.知道一般的 class 实例可以在其生命周期中动态分配新属性,我们不应该通过inspect追逐实例化的 object 以获得其原始 state。
But in context of inspection of initialization phase (instance varnames/attributes) of potential "designed" instance you can apply the following approach (digging into inspect.getmembers ):但是在检查潜在“设计”实例的初始化阶段(实例变量名/属性)的上下文中,您可以应用以下方法(深入inspect.getmembers ):

from typing import List
import inspect
import datetime as dt

class Apple:

    def __init__(self,color:str,size:int) -> None:

        self.log_time = dt.datetime.now()
        self.color = color
        self.size = size

def get_init_varnames(class_obj:object) -> List[str]:
    '''Finds instanse varnames/attributes (on initialization phase).'''
    init_code_obj = next(filter(lambda m: m[0] == '__init__', inspect.getmembers(class_obj)))[1]
    init_code = init_code_obj.__code__
    return init_code.co_names[-init_code.co_nlocals:]

print(get_init_varnames(Apple))

('log_time', 'color', 'size')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM