python面向对象(3):数据封装&访问限制

2020-04-09  本文已影响0人  _百草_
# -*- coding:utf-8 -*-
"""
@author:wlh
@file:dataEncapsulation_0408.py
@time:2020/04/08
"""
# 面向对象编程的第一个特点:数据封装
# 每个实例都有各自的name和score等属性;通过函数来访问这些数据


class Student3(object):
    def __init__(self, name, score):
        """通过定义__init__方法,在创建实例的时候,就把name等属性绑上去"""
        self.name = name  # 成员变量
        self.score = score

    def print_score(self):
        """
        不必从外部访问,可以直接在类的内部定义访问数据的函数;这样就把数据封装起来了
        如何打印,外部无需知道,直接调用就好
        封装数据的函数,即为类的方法
        """
        print('%s : %d : %s' % (self.name, self.score, self.get_grade()))
        # AttributeError: 'Student3' object has no attribute 'grade'
        # 修改:删除方法get_grade()内局部变量grade,选择直接调用该方法

    def get_grade(self):
        """封装优点2:增加新的方法"""
        if self.score >= 90:
            # grade = 'A'
            return 'A'
        elif self.score >= 60:
            # grade = 'B'
            return 'B'
        else:
            return 'C'


std = Student3('data', 80)
std.print_score()  # 直接调用

# --------------------访问限制------------------------------
# 成员变量、类变量、函数内部的局部变量


class Variable(object):
    classVa = 100  # 类变量
    __class = 'no'  # 不被外部调用

    def __init__(self, name):
        self.memVal = 'name'  # 成员变量 类的构造函数内,以self.X来定义
        self.menClass = self.__class * 2  # 类内部可以调用__开头的属性
        self.__name = name

    def men_function(self):
        funVal = {12: 34}   # 方法内变量,仅该方法内可以使用
        return

    def get_name(self):
        if len(self.__name) > 25:
            raise ValueError('long name!')
        return self.__name


inst = Variable('Lily Wang')  # 实例化
print(Variable.classVa)  # 类名调用类变量 100
print(inst.classVa)  # 实例调用类变量 100
'''
inst.classVa = 99  # 修改实例的类变量
print(inst.classVa)  # 实例调用类变量 99
print(Variable.classVa)  # 类名调用类变量 100

Variable.classVa = 98  # 修改类的类变量
print(inst.classVa)  # 实例调用类变量 99
print(Variable.classVa)  # 类名调用类变量 98
inst2 = Variable()
print(inst2.classVa)

# print(Variable.memVal)  # 类名调用成员变量 AttributeError: type object 'Variable' has no attribute 'memVal'
print(inst.memVal)  # 实例调用成员变量
'''
# 内部属性不被外部访问,可以把属性名前加上两个下划线
# 在python中,变量名若已__开头,则就变成私有变量(private),只有内部可以访问,外部不能访问
# 外部代码不能随意修改对象内部状态==>通过访问限制的保护,代码更加健壮
# print(inst.__class)  # 'Variable' object has no attribute '__class'
print(inst.menClass)  # 类内部可以调用

# 若是外部代码要获取name怎么办?可以给类添加get_name方法
print(inst.get_name())
'''
def get_score(self):
    return self.__name
'''

# 为何多定义一种方法? 因为在方法中,可以对参数做检查,避免传入无效的参数
'''
    def get_name(self):
        if len(self.__name) > 25:
            raise ValueError('long name!')
        return self.__name
'''

# __XXX__即以双下划线开头,且以双下划线结尾的变量,是特殊变量。特殊变量可以直接访问,不是private变量
# 双下划线的变量一定不能外部访问吗?
print(inst._Variable__name)  # access to a protected member;不建议使用

# 约定俗称的规定,一个下划线开头的变量,虽可以访问,但视为私有变量,不随意访问

inst.__name = 100  # 为类新增变量__score,但实际上与内部的__score不是一个变量
print(inst.__name)  # 输出:100
# 类内部的__name已被Python解释器自动改为 _Variable__name,而外部代码给 inst 新增了一个__name变量
print(inst.get_name())  # 输出:Lily Wang

上一篇 下一篇

猜你喜欢

热点阅读