标签:
# encoding: utf-8 ‘‘‘ 1. python约定类定义中"__"开头(至多一个"_"结尾)的属性为"相对"的私有属性 2. 私有属性在类及其子类定义中是"可见"的,在 其它范围正常访问是相对"不可见"的 3. 留下子类可以修改父类私有属性的口子方便debug测试等 4. 在类定义以外可以通过[‘_‘+className+‘私有属性名称‘]名称访问 5. 私有属性引入是避免类,实例等混淆和冲突,私有属性受大家"规约"约束,所以是相对的 6. 在类定义以外类似"类.私有属性"相关操作可以近似理解为类"新增"对应类属性,并在所在上下文"有效" 7. "有效"的私有属性对后续同一上下文中的类和子类实例对应属性有直接影响 8. 注意子类override父类非私有属性的情况以及类定义以外类"新增"属性时后续子类对应属性 Created on 2015年9月4日 @author: LaughLast ‘‘‘ import unittest2 _INT_DIRECT_CHANGED_TO = 3333 _INT_CHANGED_BY_INSTANCE = 3000 _CLS_PRIVATE_ATTR = ‘__private_cls_attr‘ _CLS_NON_PRIVATE_ATTR = ‘non_private_cls_attr‘ class Sample(object): ‘‘‘simple class with class attribute‘‘‘ # private attribute __private_cls_attr = 3 # non private attribute non_private_cls_attr = 3 def __init__(self): self.init_attribute_x = 1 self.init_attribure_y = 1 def add(self): return self.init_attribute_x + self.init_attribure_y @classmethod def get__private_cls_attr(cls): return cls.__private_cls_attr @classmethod def get_non_private_cls_attr(cls): return cls.non_private_cls_attr @classmethod def initvalue(cls, p, np): cls.__private_cls_attr = p cls.non_private_cls_attr = np class SampleSubCls(Sample): # private attribute __private_cls_attr = 33 # non private attribute non_private_cls_attr = 33 class ClassAttributePrivateOrNotDifference(unittest2.TestCase): def setUp(self): ‘‘‘make sure the same context of critical attr values ‘‘‘ Sample.initvalue(3, 3) SampleSubCls.initvalue(33, 33) assert Sample.get__private_cls_attr() is 3 and Sample.get_non_private_cls_attr() is 3 assert SampleSubCls.get__private_cls_attr() is 33 and SampleSubCls.get_non_private_cls_attr() is 33 def test_private_attr_definition_convention(self): ‘‘‘actual complex name of private attr with in cls‘‘‘ internal__class_int = ‘_‘ + Sample.__name__ + _CLS_PRIVATE_ATTR assert hasattr(Sample, internal__class_int) is True assert getattr(Sample, internal__class_int) is Sample.get__private_cls_attr() internal__subclass_int = ‘_‘ + SampleSubCls.__name__ + _CLS_PRIVATE_ATTR assert hasattr(SampleSubCls, internal__subclass_int) is True assert getattr(SampleSubCls, internal__subclass_int) is SampleSubCls.get__private_cls_attr() def test_hasattr_diff(self): ‘‘‘cls private attr sees as "invisible" out of its cls definition ref: hasattr(cls,private_attr) return False ‘‘‘ assert hasattr(Sample, _CLS_PRIVATE_ATTR) is False and hasattr(Sample, _CLS_NON_PRIVATE_ATTR) is True assert hasattr(SampleSubCls, _CLS_PRIVATE_ATTR) is False and hasattr(SampleSubCls, _CLS_NON_PRIVATE_ATTR) is True def test_class_dotted_assignment_effects_on_class(self): ‘‘‘cls dotted assignment to private attr out of cls definition sees as a "new" attr of the running context away from original notice the difference of sub cls ‘‘‘ Sample.__private_cls_attr = _INT_DIRECT_CHANGED_TO Sample.non_private_cls_attr = _INT_DIRECT_CHANGED_TO assert Sample.get__private_cls_attr() is 3, ‘original value of private attr in cls definition must be unchanged‘ assert Sample.get_non_private_cls_attr() is _INT_DIRECT_CHANGED_TO, ‘original value of non private attr in cls definition must be changed‘ assert SampleSubCls.get__private_cls_attr() is 33, ‘super cls private attr can be changed in sub cls definition, on the contrary,Nope‘ assert SampleSubCls.__private_cls_attr is _INT_DIRECT_CHANGED_TO, ‘super cls has a "new" private attr in the context,so does sub cls‘ assert SampleSubCls.non_private_cls_attr is 33 and SampleSubCls.get_non_private_cls_attr() is 33, ‘sub cls overrided non private attr in super cls and kept it within itself‘ def test_class_dotted_assignment_effects_on_instance(self): ‘‘‘cls dotted assignment to attr out of cls definition generally changes the relative attr of instance in the same running context notice the difference of sub cls ‘‘‘ Sample.__private_cls_attr = _INT_DIRECT_CHANGED_TO Sample.non_private_cls_attr = _INT_DIRECT_CHANGED_TO assert Sample().__private_cls_attr is _INT_DIRECT_CHANGED_TO and Sample().non_private_cls_attr is _INT_DIRECT_CHANGED_TO, ‘the same changes of cls "new" attr must be made to its instance‘ instance = Sample() instance.__private_cls_attr = _INT_CHANGED_BY_INSTANCE instance.non_private_cls_attr = _INT_CHANGED_BY_INSTANCE assert Sample.__private_cls_attr is _INT_DIRECT_CHANGED_TO and Sample.non_private_cls_attr is _INT_DIRECT_CHANGED_TO, ‘the changes of instance "new" attr must not be made to its cls ‘ assert SampleSubCls().__private_cls_attr is _INT_DIRECT_CHANGED_TO, ‘super cls has a "new" private attr in context,so do sub cls and its instance‘ assert SampleSubCls.get_non_private_cls_attr() is 33 and SampleSubCls().non_private_cls_attr is 33, ‘sub cls overrided non private attr in super cls and kept it within itself‘ instance_sub = SampleSubCls() instance_sub.__private_cls_attr = _INT_CHANGED_BY_INSTANCE instance_sub.non_private_cls_attr = _INT_CHANGED_BY_INSTANCE assert Sample.__private_cls_attr is _INT_DIRECT_CHANGED_TO and Sample.non_private_cls_attr is _INT_DIRECT_CHANGED_TO, ‘the changes of instance "new" attr must not be made to its super cls‘ if __name__ == ‘__main__‘: unittest2.main()
[有码有真相]python类私有属性等要点理解及测试示例代码
标签:
原文地址:http://my.oschina.net/laugh2last/blog/501405