为了账号安全,请及时绑定邮箱和手机立即绑定

动态创建类的属性

动态创建类的属性

一只甜甜圈 2021-09-02 15:06:19
看看这个代码片段:class Face():    passclass Cube():    def __init__(self):        self.faces = {                'front': Face(1),                ...                }    @property    def front(self):        return self.faces['front']    @front.setter    def front(self, f):        pass我已经为所有面创建了 getter 和 setter。有没有办法让这段代码更紧凑,也许是通过动态创建 getter 和 setter?
查看完整描述

3 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

以下代码假设您

  • 有理由使用self.facesdict 而不是front直接在实例上设置属性

  • 和/或想要为self.faces.

否则,这个练习是毫无意义的,因为正如 Corentin Limier 指出的那样,您可以简单地设置self.front = Face(1),等等。


您可以使用描述符、保存人脸名称的类变量和类装饰器。将描述符视为可重用的属性。

在以下示例代码中,我仅出于演示目的numFace和 face添加了一个实例变量'side'

class FaceDescriptor:

    def __get__(self, instance, owner):

        # your custom getter logic


        # dummy implementation

        if instance is not None:                

            return instance.faces[self.face]


    def __set__(self, instance, value):

        # your custom setter logic


        # dummy implementation

        instance.faces[self.face] = value


def set_faces(cls):

     for face in cls._faces:

         desc = FaceDescriptor()

         desc.face = face

         setattr(cls, face, desc)

     return cls


class Face():

    def __init__(self, num):

        self.num = num   


@set_faces

class Cube():

    _faces = ['front', 'side']


    def __init__(self):

        self.faces = {face:Face(i) for i, face in enumerate(self._faces, 1)}

在行动:


>>> c = Cube()                                                                                                                                                                                         

>>> c.front.num                                                                                                                                                                                         

1

>>> c.side.num                                                                                                                                                                                          

2

>>> c.front = 'stuff'                                                                                                                                                                                   

>>> c.front                                                                                                                                                                                             

'stuff'

>>> c.faces                                                                                                                                                                                             

{'front': 'stuff', 'side': <__main__.Face at 0x7fd0978f37f0>}


查看完整回答
反对 回复 2021-09-02
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

如果你真的想这样做,你可以使用__getattr__和 __setattr__:


class Cube:


   ...   


   def __getattr__(self, item):

        return self.faces[item]


   def __setattr__(self, item, value):

        self.faces[item] = value

但是当你front在方法中设置时,__init__你也可以让它成为一个普通成员......


查看完整回答
反对 回复 2021-09-02
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

假设这就是你的班级所做的一切,你可以做类似的事情


class Cube:

   ...


def __getattr__(self, name):

    return self.faces[name]


def __setattr__(self, name, value):

    self.faces[name] = value


查看完整回答
反对 回复 2021-09-02
  • 3 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信