Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有办法在不创建类实例的情况下获取类实例属性?_Python_Dictionary_Class Instance Variables - Fatal编程技术网

Python 有没有办法在不创建类实例的情况下获取类实例属性?

Python 有没有办法在不创建类实例的情况下获取类实例属性?,python,dictionary,class-instance-variables,Python,Dictionary,Class Instance Variables,下面是我的第一个问题的链接:所以我试图从字典中创建类实例,该字典包含类没有的键。例如: class MyClass(object): def __init__(self, value1, value2): self.attr1 = value1 self.attr2 = value2 dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'} 在创建类实例之前,我必须

下面是我的第一个问题的链接:
所以我试图从字典中创建类实例,该字典包含类没有的键。例如:

class MyClass(object):
    def __init__(self, value1, value2):
        self.attr1 = value1
        self.attr2 = value2

dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}
在创建类实例之前,我必须从dict中删除这个
冗余密钥

dict.pop('redundant_key', None)
new_instance = MyClass(**dict)
问题是我有几个类和几个dict,其中包含很多键(我有几个json格式的响应,它们表示为dict,我想从这个json响应创建对象)。我已经从前面的问题中找到了一个临时解决方案——如何删除多余的密钥。我只能使用我需要的密钥从旧dict创建新dict:

new_dict = {key: old_dict[key] for key in allowed_keys}
下面是代码:

class MyClass(object):
    def __init__(self, value1, value2):
        self.attr1 = value1
        self.attr2 = value2

dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}
new_instance = MyClass(**{key: dict[key] for key in allowed_keys})
我现在只需要获得
允许的密钥
。那么问题是——有没有办法在不创建类实例的情况下获取类实例属性?

免责声明:这回答了OP的问题(获取实例属性),而不是他们需要什么。这似乎是构造函数的参数列表

你不能做你想做的事。在python中,属性被动态地添加到类的实例中。同一类的两个实例可以具有不同的属性。好。。。确切地说,有一些东西叫做实例属性和类属性

实例属性是与类的实例关联的属性。类属性与其定义相关联,即如果您编写(
MyClass.foo

如果查看该示例,这些属性是在
self
上的
\uuuu init\uuuu
过程中添加的,因此它们是实例属性

您可以做的是创建一个有效实例并检查它(查看下面的示例),提供
允许的\u键的静态列表(例如作为类属性),或者以某种方式要求
允许的\u键作为构造函数参数。所有这些都是一种权宜之计,因为你真正需要的是不可能的。他们各有利弊

例如:


下面是如何做您正试图做的事情:用适当的参数实例化您的类。请注意,您不是在检查
\uuu init\uuu
创建的属性,而是检查它接受的参数。不管它对这些属性做了什么,调用构造函数时不必担心这一点

myparams = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}
usable = { k:v for k, v in myparams if k in MyClass.__init__.__code__.co_varnames }
new_instance = MyClass(**usable)
为了清晰起见,我使用了一个经过过滤的词典理解,但你当然可以一步完成


请注意,如果您的词典中碰巧包含键
self
:-),您将遇到问题如果您不信任数据源,您可能需要将其过滤掉。

如果您坚持使用过于通用的字典来初始化对象,只需定义接受但忽略额外的键即可

class MyClass(object):
    def __init__(self, attr1, attr2, **kwargs):
        self.attr1 = attr1
        self.attr2 = attr2

d = {'attr1': 'value1', 'attr2': 'value2', 'extra_key': 'value3'}
new_instance = MyClass(**d)
如果无法修改(如果它继承自SQLAlchemy声明性基,则会出现这种情况),请添加一个替代构造函数以接受所有关键字参数,但选择需要的参数

class MyClass(Base):
    @classmethod
    def from_dict(cls, **kwargs):
        # Let any KeyErrors propagate back to the caller.
        # They're the one who forgot to make sure **kwargs
        # contained the right keys.
        value1 = kwargs['attr1']
        value2 = kwargs['attr2']
        return cls(value1, value2)

new_instance = MyClass.from_dict(**d)

您应该提到,您需要SQLAlchemy映射器类的列。这是一项容易得多的任务:

dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}
columns = YourTable.__table__.columns.keys()
entry = YourTable(**{k: dict[k] for k in columns})

首先,这是不可能的,其次,您希望获取函数的参数,而不是实例的属性,这是通过检查可以实现的。从技术上讲,这是不可能的,属性可以动态地添加和删除到实例中,因此在没有实际实例的情况下使用它们是没有意义的。我不知道你为什么想要它,当
attr1
时,
allowed\u keys
在哪里定义了
attr1
attr2
allowed\u keys
中,
attr2
是类实例'attributes@luk32我可以自己定义允许的_键,但它大约有10个dict和10-20个不同的键,所以我考虑了自动填充允许的_键的方法。我真的不需要类实例的属性,我需要在
\uuuuu init\uuuuu
method@alexis:17分钟前我就是这么说的。但OP不会听:-(我真的不需要类实例的属性,我需要在
\uuuuu init\uuuuu
方法期间创建的属性。有没有办法获得在
\uuuuuu init\uuuuuu
方法期间添加的属性?有类属性概念的情况是,类具有
\uuuu插槽而不是属性字典。这个解决方案初始化可能有副作用,在每种情况下都不起作用,而且你已经需要知道
\uuu init\uuu
的参数来实例化类。我不是说这是个好主意。另外,你知道参数的数量,而不是似乎需要的属性名称。@Daniel我想我明白了。我写了一个小免责声明。问题是这是一种误导。另外,我认为以上想法是唯一能与
*args
**kwargs
一起工作的解决方案。我认为答案仍然有一定的价值。这是一个非常好的解决方案,但问题是我拥有的类是由sqlalchemy创建的。我只是根据声明性类定义风格编写它.So MyClass.\uuuu init\uuuuu.\uuuu code\uuuu.co\u varnames返回类似于
('self','kwargs','new\u state')的内容
我不能编写
\uuuu init\uuuu
方法,因为我想在这种情况下,你的问题应该针对sqalchemy!你必须深入研究它的内部,找出你感兴趣的类接受哪些参数。可能有一些东西你可以使用(也许它的初始值设定者有一种管理允许的关键字参数的标准方法),也可能没有。一般来说,如果不运行或模拟函数,您无法期望知道函数将执行什么操作。我还强烈怀疑创建的属性将取决于您提供的关键字参数——这意味着即使您可以在没有参数的情况下实例化构造函数来实例化示例对象,您也不会看到实例化对象中所有可能的属性
dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}
columns = YourTable.__table__.columns.keys()
entry = YourTable(**{k: dict[k] for k in columns})