封装之如何隐藏对象及封装的意义

python中通常在属性和方法前加__(两条下划线)来进行属性和方法的隐藏。

特点:

1.在类外无法直接obj.__AttrName

2.在类内部可以直接使用obj.__AttrName

3.子类无法覆盖父类__开头的属性

1.在类外无法直接obj.__AttrName

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print('run')

    def sing(self):
        self.__run()
        print('sing')

b = A('gaohui', 100)
print(b.__name)


报错:
AttributeError: 'A' object has no attribute '__name'

2.在类内部可以直接使用obj.__AttrName

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print('run')

    def sing(self):
        self.__run()
        print('sing')

b = A('gaohui', 100)
b.sing()

输出结果:
run
sing

此时的__run正常输出了,因为在类的定义时,self.__run()已经便成了self._A__run()

3.子类无法覆盖父类__开头的属性

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print('run')

    def sing(self):
        self.__run()
        print('sing')

class B(A):
    def __init__(self, name, age, life):
        super().__init__(name, age)
        self.__life = life

    def __run(self):
        print('---')
        

print(A.__dict__)
print(B.__dict__)


输出结果:
{'__module__': '__main__', '__init__': <function A.__init__ at 0x1068190d0>, '_A__run': <function A.__run at 0x1068192f0>,
{'__module__': '__main__', '__init__': <function B.__init__ at 0x106819730>, '_B__run': <function B.__run at 0x1068197b8>,

两个run方法的属性是不一样的。

方法和属性隐藏需要注意的地方:

1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print('run')

    def sing(self):
        self.__run()
        print('sing')

a = A('gaohui', 100)
print(a._A__name)


输出结果:
gaohui

2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print('run')

    def sing(self):
        self.__run()
        print('sing')

A.__b = 1
a = A('gaohui', 100)
print(a._A__name)
print(A.__b)


输出结果:
gaohui
1

当类已经定义好了,再次定义时不会变形成隐藏的模式。

3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

class A:
    def __fa(self):     *_A__fa
        print('from A')

    def test(self):
        self.__fa()  # 此时的fa方法是变形过的_A__fa,所以之行类A中的fa方法


class B(A):
    def __fa(self):    *_B__fa
        print('from B')


b = B()
b.test()


输出结果:

from A

封装数据属性的意义:明确的区分内外,控制外部对隐藏的属性的操作行为

class A:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def tell_info(self):        # 可以通过一个接口来显示被隐藏的数据,不能直接被外部调用
        print('name is %s, age is %s' % (self.__name, self.__age))

    def search_info(self, name, age):
        if not isinstance(name, str):  # 检验是不是字符串
            print('姓名为字符串')
            return
        if not isinstance(age, int):
            print('年龄已经为整数')
            return
        self.__name = name
        self.__age = age
        self.tell_info()


st = A('GAO', 23)
print(st.__dict__)
#st.search_info('Gww', 23)  # 可以通过一个接口来修改name和age,而不是直接修改

封装方法:

class ATM:
    def __card(self):
        print('插卡')

    def __auth(self):
        print('用户验证')

    def __input(self):
        print('输入取款金额')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()


a = ATM()
a.withdraw()
原文地址:https://www.cnblogs.com/huizaia/p/9670021.html