码迷,mamicode.com
首页 > 编程语言 > 详细

[有码有真相]python类私有属性等要点理解及测试示例代码

时间:2015-09-05 20:55:22      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

# 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!