gpt4 book ai didi

python - 在 Python 中,统计类中变量的数量或防止添加新的类变量

转载 作者:太空宇宙 更新时间:2023-11-03 12:17:36 25 4
gpt4 key购买 nike

在python中,有没有一种方法可以防止在定义对象后添加新的类变量?

例如:

class foo:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3

bar = foo()
try:
bar.d = 4
except Exception, e:
print "I want this to always print"

或者,有没有办法计算对象中变量的数量?

class foo:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def count(self):
...

bar = foo()
if bar.count() == 3:
print "I want this to always print"

我想到的唯一方法是使用字典或列表:

class foo:
def __int__(self):
self.dict = {'foo':1, 'bar':2}
self.len = 2
def chk():
return self.len == len(self.list)

但是这样做对于python来说感觉比较麻烦。 (obj.dict['foo'])。如果可能的话,我更喜欢 obj.foo。

我想要这个,这样我就不会在想要更改现有变量时不小心声明一个变量。

f = foo()
f.somename = 3
...
f.simename = 4 #this is a typo

if f.somename == 3:
solve_everything()

最佳答案

我建议使用 __setattr__ 来避免 __slots__ 的奇怪之处。

你在使用 __setattr__ 时一定要小心,因为它负责设置 所有 实例属性,包括你在 __init__ 中设置的那些>。因此它必须有某种方式知道什么时候允许设置属性,什么时候拒绝它。在此解决方案中,我指定了一个特殊属性来控制是否允许使用新属性:

class A(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
self.freeze = True

def __setattr__(self, attr, value):
if getattr(self, "freeze", False) and not hasattr(self, attr):
raise AttributeError("You shall not set attributes!")
super(A, self).__setattr__(attr, value)

测试:

a = A()
try:
a.d = 89
except AttributeError:
print "It works!"
else:
print "It doesn't work."
a.c = 42
print a.a
print a.c
a.freeze = False
a.d = 28
a.freeze = True
print a.d

结果:

It works!14228

Also see gnibblers answer that wraps this concept neatly up in a class decorator, so it doesn't clutter up the class definition and can be reused in several classes without duplicating code.


EDIT:

Coming back to this answer a year later, I realize a context manager might solve this problem even better. Here's a modified version of gnibbler's class decorator:

from contextlib import contextmanager

@contextmanager
def declare_attributes(self):
self._allow_declarations = True
try:
yield
finally:
self._allow_declarations = False

def restrict_attributes(cls):
cls.declare_attributes = declare_attributes
def _setattr(self, attr, value):
disallow_declarations = not getattr(self, "_allow_declarations", False)
if disallow_declarations and attr != "_allow_declarations":
if not hasattr(self, attr):
raise AttributeError("You shall not set attributes!")
super(cls, self).__setattr__(attr, value)
cls.__setattr__ = _setattr

return cls

下面是如何使用它:

@restrict_attributes
class A(object):
def __init__(self):
with self.declare_attributes():
self.a = 1
self.b = 2
self.c = 3

所以每当你想设置新的属性时,只要像上面那样使用with语句即可。也可以从实异常(exception)部完成:

a = A()
try:
a.d = 89
except AttributeError:
print "It works!"
else:
print "It doesn't work."
a.c = 42
print a.a
print a.c
with a.declare_attributes():
a.d = 28
print a.d

关于python - 在 Python 中,统计类中变量的数量或防止添加新的类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11964895/

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