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