封装的定义

封装是面向对象编程的一个重要概念。它是指将类中部分属性和方法加以隐藏与保护,使其只能在类内部使用而不能被外部直接访问。

封装最重要的优点有2条:一是提高了数据安全性、二是提高了代码健壮性。

封装的方法

在类内部定义的变量前加双下划线即表示该变量是私有的,外部不能直接访问。

class User:
    __private = 'secret'

    def __print():
        print(f'不能告诉你{User.__private}')

封装的原理

加了双下划线的变量为啥不能从类的外部调用?请认真观察private和print两个变量:

class User:
    __private = 'secret'

    def __print():
        print(f'不能告诉你{User.__private}')

print(User.__dict__)

out:
{'__module__': '__main__', '_User__private': 'secret', '_User__print': <function User.__print at 0x0000026476656280>, '__dict__': <attribute '__dict__' of 'User' objects>, '__weakref__': <attribute '__weakref__' of 'User' objects>, '__doc__': None}

类内部定义双下划线开头的变量会被python自动转换成 单下划线类名 双下划线 变量名。在类外部不能定义私有变量,即类外部定义双下划线开头的变量不会被自动转换。所以在类外部直接访问私有变量会报错。在类内部可以直接访问私有变量。

另外知道python封装原理后,在类外部实际上还是可以直接访问私有变量,案例如下:

class User:
    __private = 'secret'

    def __print():
        print(f'不能告诉你{User.__private}')

print(User._User__private)
User._User__print()

out:
secret
不能告诉你secret

但是强烈建议不要在类外部直接访问类内部的私有属性,这样做破坏了封装的规则,不利于数据安全性和代码健壮性。

封装的案例

运用封装的有很多,下面举一个小案例:

class User:
    def __init__(self, name, password):
        self.name = name
        self.__password = password

    def chgpwd(self):
        pwd = input('请输入旧密码:')
        if pwd == self.__password:
            pwd1 = input('请输入新密码:')
            pwd2 = input('请再输入一次:')
            if pwd1 == pwd2 and len(pwd1) >= 6:
                self.__password = pwd1
                return False
        return True


n1 = User('张三', '123456')
while n1.chgpwd():
    print('密码修改失败,请重试!')

在上述代码中,__password是私有属性,不能直接修改!若要修改必须通过chgwd()方法,在该方法中有验证旧密码和重复新密码的功能,确保修改密码合规。在多人配合的项目中封装是不可或缺的手段。经常用来验证输入的数据值是否合理等等。