面向对象之封装

在定义类时,在类内部函数属性和数据属性之前加’__’(两个下划线),再和以前一样去访问属性就会报错。

class Student:
    __school = '北大'

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

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


student = Student('小明', 18)
print(Student.__school)
print(Student.__run)
print(student.__name)
# AttributeError: type object 'Student' has no attribute '__school'

发生了什么?我们看下__dict___

print(Student.__dict__)

{'__module__': '__main__', '_Student__school': '北大', '__init__': <function Student.__init__ at 0x0000017BE6766158>, '_Student__run': <function Student.__run at 0x0000017BE67661E0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

发现我们定义的__school和函数__run变成了 ‘_Student__school’, ‘_Student__run’
类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式,其实如果非要访问是可以访问的,
那我们换个方式访问下:

print(Student._Student__school)
# 北大

print(student.__dict__)
# {'_Student__name': '小明', '_Student__age': 18}

print(student._Student__name)
# 小明

这其实是一种变形,变形后,外部无法直接访问,内部可以访问

class Student:
    __school = '北大'

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

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

    def walk(self):   # 调用run
        self.__run()


student = Student('小明', 18)
student.walk()
# running 表示内部直接访问成功。

意义在于保护内部属性数据不被随意访问和更改,可以将数据隐藏起来之后,内部设置一个函数访问属性,添加条件限制,外部访问时调用此函数,必须满足条件限制。

class Student:
    __school = '北大'

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

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

    def walk(self):
        self.__run()

    def tell_info(self):
        print('姓名:%s 年龄:%s' %(self.__name, self.__age))

    def set_info(self, name, age):
        if isinstance(name,str) and isinstance(age, int):
            self.__name = name
            self.__age = age
        else:
            print('数据类型错误')
s1 = Student('小明', 18)
s1.tell_info()
# 姓名:小明 年龄:18

s1.tell_info()
# 姓名:小明 年龄:18

s1.set_info('小明', 20)
s1.tell_info()
# 姓名:小明 年龄:20

另外,如果父类不想子类覆盖部分功能,可以利用隐藏将功能私有化:

class A:

    def f(self):
        print('from A')

    def test(self):
        self.f()


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


b = B()
b.test()

from B
class A:

    def __f(self):   # self._A__f
        print('from A')  

    def test(self):
        self.__f()  # self._A__f


class B(A):
    def __f(self):  # self._B__f
        print('from B')


b = B()
b.test()


from A
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值