Python全栈开发实战学习18

封装

狭义上的封装——面向对象的三大特征之一
属性和方法都隐藏起来,不让看见

如何隐藏

在python中用双下划线开头的方式将属性隐藏起来,设置成私有的
其实这仅仅是一种变形操作
类中所有双下划线开头的名称如__x都会自动变形成:_类名_x的形式

class Person:
    __key = 123  # 私有的静态属性
    def __init__(self,name,pwd):
        self.name = name
        self.__pwd = pwd  # 私有属性
    def __get_pwd(self):  # 私有方法
        return self.__pwd # 只要是在类内部使用私有属性就会自动加上__类名

    def login(self):
        self.__get_pwd()  # 正常的方法调用私有方法
class A:
    __N = 0 # 私有静态属性
    def __init__(self):
        self.__X = 10  # 变形为self._A__X
    def __foo(self):   # 变形为_A__foo
        print('from A')
    def bar(self):
        self.__foo() # 只有在类内部才可以通过__foo的形式访问到的
    
# A._A__N是可以访问的,即这种操作并不是严格意义上的限制外部访问,仅仅是一种语法意义上的变形

特点

  1. 类中定义的私有属性和私有方法只能在类中使用,直接调用__X即可
  2. 外部无法通过__X直接调用
  3. 子类定义的__X不会覆盖父类定义的__X,因为自动更名为_子类名__X和_父类名__X
  4. 父类的私有属性不能由子类调用

未引入私有方法:

class A:
    def fa(self):
        print('from A')
    def test(self):
        self.fa()

class B(A):
    def fa(self):
        print('from B')

b = B()
b.test()       # from B

引入私有方法后:

class A:
    def __fa(self):
        print('from A')
    def test(self):
        self.__fa()

class B(A):
    def fa(self):
        print('from B')

b = B()
b.test()      # from A

封装不是单纯意义的隐藏

封装数据

将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,一次完成对数据属性操作的严格控制。

class Teacher:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    def get_name(self):
        return self.__name
    def set_name(self,newName):
        if type(newName) is str and not newName.isdigit():
            self.__name = newName
        else:
            print('名字必须是字符串形式')

egon = Teacher('egon',18)
name = egon.get_name()
print(name)
egon.set_name('2')
egon.set_name('alex')
print(egon.get_name())

==========
结果
egon
名字必须是字符串形式
alex
封装方法:目的是隔离复杂度

1.取款功能由很多功能组成:插卡,密码认证,输入金额,打印账单,取钱等
2.对使用者来说,只需知道取款这个功能即可,其余功能我们都可以隐藏起来
3.隔离了复杂,同时提升了安全性

class ATM:
    def __insert_card(self):
        print('插卡')
    def __login(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')
    def withdraw(self):
        self.__insert_card()
        self.__login()
        self.__input()
        self.__print_bill()
        self.__take_money()

a = ATM()
a.withdraw()
子类不能继承父类的私有属性和方法
class A:
    __X = '123'

class B(A):
    print(A.__X)    # AttributeError: type object 'A' has no attribute '_B__X'

B()

property

property是一种装饰器函数,只在面向对象中使用

property可以将类中的方法伪装成属性

from math import pi

class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def perimeter(self):
        return 2*pi*self.r
    @property
    def area(self):
        return pi*self.r**2

c = Circle(5)
print(c.perimeter)     #31.41592653589793
print(c.area)		   #78.53981633974483
property可以提供set和get方法去设置和获取
class Foo:
    def __init__(self,name):
        self.__name = name

    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,newName):
        if not isinstance(newName,str):
            raise TypeError('%s must be str'%newName)
        self.__name = newName
    @name.deleter
    def name(self):
        raise TypeError('无法删除')
f = Foo('alex')
print(f.name)	# alex
f.name = 10     # TypeError: 10 must be str
# del f.name  	# TypeError: 无法删除
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值