动态创建类属性

Tom*_*mie 6 python metaprogramming class python-3.x

我正在寻找一种动态创建具有可通过典型实例符号访问的特定属性的类的方法。

       DynoOne = createClass('DynoOne',props=['A','B'])
       d = DynoOne (database='XYZ')
       d.A = d.B + 1

       DynoTwo = createClass('DynoTwo',props=['A','C','E'])
       q = DynoTwo (database='QRS')
       q.A = q.C + 2*q.E
Run Code Online (Sandbox Code Playgroud)

实际如何获取和修改“道具”的细节将被隐藏。当新道具可用时,这也使添加新道具的访问变得更加容易。

我已经尝试了以下技术,以了解python如何动态产生基本的类属性:

类工厂产生简单的类结构类?

我最初对python的阅读表明,类属性是处理引入getter / setter方法进行访问的一种方法。

尚不清楚如何在工厂构造函数方法中动态指定属性名称(无论使用装饰器还是显式的property()调用)

例如,使用property()。。。

   class DynamicClass( someBase ):

       def dynamic_getter(self):
           # acquire "stuff"
           return stuff

       def dynamic_setter(self,stuff):
           # store  "stuff"
           pass 

       dynamic_property_name = property(fget=dynamic_getter,fset=dynamic_setter)

Run Code Online (Sandbox Code Playgroud)

当类被声明/构造时,我需要为每个请求的道具创建一个集合。例如,DynoOne类将为“ A”和“ B”具有单独的属性/设置器/获取器。

我怀疑基于模板的eval()策略会起作用,但是我可能会缺少一些更基本,更有效的技术。

启发和学习机会受到赞赏:-)

jua*_*aga 4

of 的三个参数type允许您动态创建类。所以,画一个草图:

def dynamic_getter(self):
    # acquire "stuff"
    return stuff

def dynamic_setter(self,stuff):
    # store  "stuff"
    pass 

DynamicClass =  type('DynamicClass', (SomeBase,), {"dynamic_property_name":property(fget=dynamic_getter,fset=dynamic_setter)})
Run Code Online (Sandbox Code Playgroud)

或者,更具体地说:

In [1]: class SomeBase:
   ...:     def __init__(self):
   ...:         self._foo = 42
   ...:
   ...: def dynamic_getter(self):
   ...:     # acquire "stuff"
   ...:     return self._foo
   ...:
   ...: def dynamic_setter(self,stuff):
   ...:     # store  "stuff"
   ...:     pass
   ...:
   ...: DynamicClass =  type('DynamicClass', (SomeBase,), {"dynamic_property_name":property(fget=dynamic_getter,fset=dynamic_setter)})

In [2]: instance = DynamicClass()

In [3]: instance.dynamic_property_name
Out[3]: 42
Run Code Online (Sandbox Code Playgroud)

注意:type字面上是一个类对象,就像任何其他对象一样,以三参数形式调用它是新类对象实例的构造函数,它是创建其他类对象的类,即元类。事实上,您可以将类定义语句视为上述内容的语法糖。

如果您发现基于模板的 with exec(如果您想使用复杂的语句,则需要exec,eval只允许表达式)方法也是可行的,如果您发现它更容易使用。事实上,这就是collections.namedtuple标准库的工作原理。

注意:您似乎对 Python 中属性的性质感到困惑。实例属性未在类上指定,相反,您需要添加一个初始化这些实例属性的函数(通常),但您可以在任何地方__init__添加实例属性,甚至在方法/类之外。