相关疑难解决方法(0)

如何动态地向类添加属性?

目标是创建一个类似于db结果集的模拟类.

因此,例如,如果数据库查询使用dict表达式返回{'ab':100, 'cd':200},那么我想看到:

>>> dummy.ab
100
Run Code Online (Sandbox Code Playgroud)

起初我想也许我可以这样做:

ks = ['ab', 'cd']
vs = [12, 34]
class C(dict):
    def __init__(self, ks, vs):
        for i, k in enumerate(ks):
            self[k] = vs[i]
            setattr(self, k, property(lambda x: vs[i], self.fn_readyonly))

    def fn_readonly(self, v)
        raise "It is ready only"

if __name__ == "__main__":
    c = C(ks, vs)
    print c.ab
Run Code Online (Sandbox Code Playgroud)

但是c.ab返回一个属性对象.

更换setattr线路k = property(lambda x: vs[i])完全没用.

那么在运行时创建实例属性的正确方法是什么?

PS我知道如何__getattribute__使用该方法?

python monkeypatching runtime properties

193
推荐指数
11
解决办法
19万
查看次数

描述符作为python中的实例属性

对于这个问题:

为什么描述符不能成为实例属性?

有人回答说:

描述符对象需要存在于类中,而不是实例中

因为这是实施的方式__getattribute__.

一个简单的例子.考虑描述符:

class Prop(object):

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return obj._value * obj._multiplier

    def __set__(self, obj, value):
        if obj is None:
            return self
        obj._value = value

class Obj(object):

    val = Prop()

    def __init__(self):
        self._value = 1
        self._multiplier = 0
Run Code Online (Sandbox Code Playgroud)

考虑每个obj都有多个Prop的情况:我需要使用唯一的名称来标识值和乘数(比如这里.拥有一个每个实例描述符对象将允许将_multiplier(和_value)存储在描述符本身中,简化了一些事情.

要实现每个实例描述符属性,您需要:

  1. 创建每个实例类请参见此处
  2. 覆盖__getattribute__ 见这里

我知道之前已经提出过类似的问题,但我还没有找到真正的解释:

  1. 为什么Python是这样设计的?
  2. 存储描述符所需信息但是每个实例的建议方法是什么?

python descriptor

21
推荐指数
2
解决办法
6881
查看次数

向现有对象实例添加属性

我想创建一个具有某些属性的对象。我想动态添加它们。与向现有对象实例添加方法类似,但使用属性而不是方法。下面是一个简单的例子。

我喜欢动态创建:

class A():
    @property
    def a(self):
        return self._a
    @a.setter
    def a(self, x):
        self._a = 10*x

    @property
    def b(self):
        return self._b
    @b.setter
    def b(self, x):
        self._b = 10*x
Run Code Online (Sandbox Code Playgroud)

要使用方法来做到这一点,我会这样做:

class B():
    def __init__(self):
        for i in range(70,80):
            self.__dict__[chr(i)] = types.MethodType(lambda self,x: x*i, self)
Run Code Online (Sandbox Code Playgroud)

对于我尝试过的属性:

class B():
    def __init__(self):
        for i in range(70,80):
            def tmp(self, x):
                self._x = i*x
            self.__dict__[chr(i)] = property(fget=lambda self: self._i, fset=tmp)
Run Code Online (Sandbox Code Playgroud)

我也找到了types.DynamicClassAttribute,但我不确定这是否有帮助。

这里提出了一个相关问题,关于向类添加属性(在 python 2 中): Dynamically add @property in python。我不知道如何将其扩展到类的实例。

背景 …

python

6
推荐指数
1
解决办法
3102
查看次数

猛击在Python的物产的鸭子

我希望能够将属性http://docs.python.org/library/functions.html#property添加到对象(类的特定实例).这可能吗?

关于python中鸭子打孔/猴子修补的其他一些问题:

将方法添加到现有对象实例

Python:在运行时更改方法和属性

更新:由delnan在评论中回答

在python中动态添加@property

python monkeypatching properties

5
推荐指数
1
解决办法
2780
查看次数

为什么在使用obj.x语法调用时不调用Python描述符方法?

X这里有一个描述符类.我尝试X在另一个类中使用描述符Y

class X:
    def __init__(self, value):
        self.value = value

    def __get__(self, instance, owner):
        print('#### X.__get__ ####')
        return self.value

    def __set__(self, instance, value):
        print('#### X.__set__ ####')
        self.value = value

class Y:
    def __init__(self):
        self.x = X(10)

y = Y()
print(y.x)
y.x = 20
Run Code Online (Sandbox Code Playgroud)

我希望语句print(y.x)会调用x.__get__并且语句y.x = 20会调用x.__set__,但它不会发生.当我运行上面的程序时,我得到了这个输出.

<__main__.X object at 0x7fc65f947950>
Run Code Online (Sandbox Code Playgroud)

为什么没有调用描述符方法?

python descriptor python-3.x

5
推荐指数
1
解决办法
121
查看次数

在Python中动态添加属性到实例

我基本上有一个围绕词典列表的精心设计的包装器:

class Wrapper(object):
    def __init__(self, data):
        self.data = data

    def get(self, attr):
        return [d[attr] for d in self.data]
Run Code Online (Sandbox Code Playgroud)

所以,

Wrapper([{'x': 23}, {'x': 42}, {'x': 5}]).get('x')
Run Code Online (Sandbox Code Playgroud)

回报[23, 42, 5].现在我想分配速记属性,以便Wrapper.x返回相同的Wrapper.get('x').我不知道data先验中存在哪些键,所以我目前的方法是(改编自这个问题:

class Wrapper(object):
    def __init__(self, data):
        self.data = data
        for key in data[0].keys():
            setattr(self, key, property(lambda self: self.get(key)))
Run Code Online (Sandbox Code Playgroud)

因此,假设数据的所有元素都具有相同的密钥,并且它们在python中都是有效的标识符.但是,Wrapper(...).x返回,<property at 0x10a3d4838>我做错了什么?

python properties dynamic

4
推荐指数
1
解决办法
2432
查看次数