有没有什么办法让类实例的属性,而无需创建类的实例?(Is there any way to get

2019-10-23 01:50发布

这里是链接到我的第一个问题: 从字典中创建类的实例?
所以我想从其中认为类有没有钥匙字典创建类的实例。 例如:

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

dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'}

创建类的实例之前,我不得不删除此redundant_key从字典

dict.pop('redundant_key', None)
new_instance = MyClass(**dict)

问题是,我有几个类和几个类型的字典有很多键(我有一个JSON格式若干答复其表示为类型的字典,我想从这个JSON响应创建对象)。 我已经找到以前问题的临时解决方案 - 如何删除多余的按键。 我只能用我所需要的密钥创建从旧字典新字典:

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})

所有我现在需要的是让allowed_keys 。 所以现在的问题 - 是否有什么办法让类实例的属性,而无需创建类的实例?

Answer 1:

如果你坚持要用一个过于笼统的字典来初始化你的对象,只是定义__init__接受,但是忽略,多余的按键。

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)

如果你不能修改__init__ (如似乎是,如果它从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)


Answer 2:

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

你不能做你想做的。 在python属性添加到动态一个类的实例。 同一类的两个实例可以有不同的属性。 嗯......准确地说,有事情称为实例属性和属性。

实例属性与类的实例相关联的人。 类属性与它的定义,即如果你写有关( MyClass.foo

如果你看一下例子,属性的过程中添加__init__self ,使他们有实例的属性。

你可以做的是建立一个有效的实例,并检查它(看下面的例子 ),提供的静态列表allowed_keys (例如,作为类属性),或以某种方式需要allowed_keys作为构造函数的参数。 所有这些都是一种解决方法是你真正需要的是不可能的。 他们有自己的优点和缺点。

例如

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

instance = MyClass(1,2)                        # create a valid object
instance_attributes = instance.__dict__.keys() # inspect it
print(instance_attributes)


Answer 3:

以下是如何做你想要做的:用适当的参数实例化类。 请注意,你不检查的属性,这些属性__init__造成的,但它接受的参数。 不要紧,它与them--这不是你的关心,当你调用构造函数。

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)

我用清晰过滤字典理解,但你可以做到这一点在过程中的一个步骤。

PS。 请注意,如果你的字典之一恰好包含关键你有问题self 。 :-)你可能想筛选出来,如果你不能信任你的数据源。



Answer 4:

你应该提到的是,你想要一个SQLAlchemy的映射器级的列。 这是一个非常容易的任务:

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


文章来源: Is there any way to get class instance attributes without creating class instance?