2012-06-07 58 views
2

我想在初始化一个类的某些属性时禁止进一步的分配。例如;在Person实例'p'初始化后,没有人可以明确地为'ssn'(社会安全号码)属性赋值。 _ SETATTR _而分配值内_ 初始化 _方法也被称为,因此它是不是我想要的。我只想限制进一步的作业。我怎样才能做到这一点?如何限制在构造函数外设置属性?

class Person(object): 
    def __init__(self, name, ssn): 
     self.name = name 
     self._ssn = ssn 

    def __setattr__(self, name, value): 
     if name == '_ssn': 
      raise AttributeError('Denied.') 
     else: 
      object.__setattr__(self, name, value) 

>> p = Person('Ozgur', '1234') 
>> AttributeError: Denied. 
+0

只是因为在'分配__init__'还呼吁'__setattr__' – neoascetic

+0

我想你可能不得不尝试元类 –

+4

仅供参考,这实际上并不是Python如何工作。记录您的API以告诉其他开发人员不要更改它。 – detly

回答

8

的常用方法是使用“私有”属性,开始带有下划线,和只读的公共访问属性:

import operator 

class Person(object): 
    def __init__(self, name, ssn): 
     self.name = name 
     self._ssn = ssn 
    ssn = property(operator.attrgetter("_ssn")) 

请注意,这并不能真正阻止任何人改变属性_ssn,但前导_文档属性是私有的。

+2

+1。 Python的哲学是,不是用语言强制的“你不能碰这个”,而是使用以'_'开头的属性来表示实现细节 - 这意味着客户端*可以试图摆弄它,但是它们不再被覆盖通过您对后向/前向兼容性或类不变量的任何保证。所以,他们可以捣鼓,他们可以破坏事情,但它自己的错误。 – lvc

2

您可以绕过setattr通过直接分配给构造函数中的实例字典。当然,这一招总是可以被用来欺骗你雇用做出_ssn只读任何其他篮球(在经过最初写)

class Person(object): 
    def __init__(self, name, ssn):  
     self.name = name 
     self.__dict__['_ssn'] = ssn 

    def __setattr__(self, name, value): 
     if name == '_ssn': 
      raise AttributeError('Denied.') 
     else: 
      object.__setattr__(self, name, value) 
相关问题