gpt4 book ai didi

python - 如何编写元类以防止在 __init__() 之后创建新属性?

转载 作者:太空狗 更新时间:2023-10-29 21:15:00 25 4
gpt4 key购买 nike

目前,我在类的 __init__() 方法末尾覆盖类的 __setattr__() 方法以防止创建新属性 -

class Point(object):
def __init__(self):
self.x = 0
self.y = 0
Point.__setattr__ = self._setattr

def _setattr(self, name, value):
if not hasattr(self, name):
raise AttributeError("'" + name + "' not an attribute of Point object.")
else:
super(Point, self).__setattr__(name, value)

有没有一种方法可以避免手动覆盖 __setattr__() 并在元类的帮助下自动执行此操作?

离我最近的是-

class attr_block_meta(type):
def __new__(meta, cname, bases, dctry):
def _setattr(self, name, value):
if not hasattr(self, name):
raise AttributeError("'" + name + "' not an attribute of " + cname + " object.")
object.__setattr__(self, name, value)

dctry.update({'x': 0, 'y': 0})
cls = type.__new__(meta, cname, bases, dctry)
cls.__setattr__ = _setattr
return cls

class ImPoint(object):
__metaclass__ = attr_block_meta

是否有一种更通用的方法可以不需要子类属性的先验知识?
基本上,如何避免行 dctry.update({'x': 0, 'y': 0}) 并使它工作而不管类属性的名称是什么?

附言- FWIW 我已经评估了 __slots__ 和 namedtuple 选项,发现它们不符合我的需要。请不要将注意力集中在我用来说明问题的精简 Points() 示例上;实际用例涉及一个复杂得多的类。

最佳答案

不要重新发明轮子。

实现这一点的两种简单方法(不直接使用元类)是使用:

  1. namedtuple小号
  2. __slots__

例如,使用 namedtuple(基于文档中的示例):

Point = namedtuple('Point', ['x', 'y'])
p = Point(11, 22)
p.z = 33 # ERROR

例如,使用__slots__:

class Point(object):
__slots__ = ['x', 'y']
def __init__(self, x=0, y=0):
self.x = x
self.y = y

p = Point(11,22)
p.z = 33 # ERROR

关于python - 如何编写元类以防止在 __init__() 之后创建新属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32760802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com