在为类成员设置值时,如何防止输入错误?

2024-10-03 06:18:26 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑以下示例:

class A():
    def __init__(self):
        self.veryImportantSession = 1

a = A()
a.veryImportantSession = None # ok

# 200 lines below
a.veryImportantSessssionnnn = 2 # I wanna exception here!! It is typo!

如果我试图设置一个未在__init__中设置的成员,如何才能使它引发异常?在

上面的代码在执行时不会失败,但给了我一个调试问题的有趣时间。在

比如str:

^{pr2}$

谢谢!在


Tags: selfnone示例hereinitdefexceptionit
3条回答

防止输入错误的最好方法是使用诸如pyflakespylint这样的工具,这些工具将检查代码,并告诉您是否有一个不再使用的变量a.superImportantSesssssionnnn,以及其他许多东西。在

如果你坚持用代码来做,你有两个选择:

  • (ab)使用__slots____slots__的主要目的是优化内存,以便在您将拥有数百、数千或数百万个对象时,您需要使对象的足迹尽可能小。如果你走这条路,你应该确保包括__weakref__作为允许的名称之一,这样weak references将继续工作。

  • (ab)使用__setattr__的主要目的是允许运行代码来验证、操作或以其他方式获取给定的数据,并将其以正确的格式存储

重申一下,上面两个选项并不是用来做拼写检查的,当有人试图支持一个您没有预料到的用例时,您通过禁止所有可能的属性名来限制代码的有用性的努力可能不会得到认可。在

可以重写__setattr__以仅允许来自已定义列表的属性名。在

class A(object):
    def __setattr__(self, name, value):
        allowed = ('x',)
        if name in allowed:
            self.__dict__[name]  = value
        else:
            raise AttributeError('No attribute: %s' % name) 

运行中:

^{pr2}$

但是,正如{{a2}所评论的,试图让Python更像java或C++的行为通常是个坏主意,并且会导致Python提供的很多好处。如果你担心可能会漏掉的打字错误,那么花时间为你的代码编写单元测试比试图限制类的使用要好得多。在

您可以定义一个名为__slots__的类变量。有关详细信息,请参阅Language Reference。在

__slots__只在新样式的类中工作,因此在本例中需要class A(object)而不是{}。在

class A(object):
    __slots__ = ['x']
    def __init__(self):
        self.x = 1

>>> a = A()
>>> a.x = 2
>>> a.y = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'y'

相关问题 更多 >