python 面向对象 (成员可见性:公开和私有)
< 返回列表时间: 2020-05-19来源:OSCHINA
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
一.成员可见性 python 类是有分内部与外部的. 一个类里面定义了各种各样的变量 & 静态方法 类方法,都可以从外部来调用访问,这就造成类不安全,为什么


Step 1.什么叫一个类的外部访问 class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.__class__.sum += 1 print('当前班级学生总数为:' + str(self.__class__.sum )) def do_homework(self): print('homework') @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) student1.do_homework() //student1调用了do_homework(一个类在外部访问调用do_homework方法)

Step 2.什么叫一个类内部访问 def do_homework(self): self.do_work() //在do_homework调用do_work就叫做一个类的内部调用 print('homework') def do_work(self) print()

Step 3.例子1 $ vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): self.score = score print(self.name + '同学本次考试分数为:' + str(self.score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) student1.marking(59) //实例化marking方法,并进行打分 #student1.do_homework() #执行结果 $ python s4.py 小明同学本次考试分数为:59

Step 4.例子2 student1.marking(-1) 与 student1.score = -1 的区别: student1.score = -1: 直接修改了数据变量,修改了就修改了,没有任何的限制 student1.marking(-1):通过方法对数据操作,比直接对[student1.score]数据变量做修改要安全,但通过方法呢,是可以进行判断的. $ vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): self.score = score print(self.name + '同学本次考试分数为:' + str(self.score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) student1.marking(-1) #student1.do_homework() student1.score = -1class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): self.score = score print(self.name + '同学本次考试分数为:' + str(self.score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) student1.marking(-1) #student1.do_homework() student1.score = -1 //实例化数据变量 # 执行结果 $ python s4.py 小明同学本次考试分数为:-1

Step 5.对方法进行判断 为什么可以对student1.score进行赋值,是因为score成员可见性是公开的,公开 & 私有的 区别,如果一个变量或者函数是公开的话, 就可以在类的外部直接访问 如果是私有的变量或者函数在类的外部是不能直接访问或读取 def marking(self, score):
if score < 0: //如果score 值小于0
score = 0 //强行赋值score 等于0;或者使用:return '不能打负分'
self.score = score
print(self.name + '同学本次考试分数为:' + str(self.score)) $ vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): if score < 0: return '不能打负分' self.score = score print(self.name + '同学本次考试分数为:' + str(self.score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) result = student1.marking(-1) print(result) #执行结果 $ python s4.py 不能打负分

Step 6.如何把方法变成私有 python一旦在方法或变量前面加双下划线'__',那就表示这个变量是私有的,是不能在类的外部读取访问的 在marking方法前面加入双下滑线,可见执行结果是报错的 $ vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def __marking(self, score): if score < 0: return '不能打负分' self.score = score print(self.name + '同学本次考试分数为:' + str(self.score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) result = student1.__marking(78) print(result) #执行结果 $ python s4.py Traceback (most recent call last): File "s4.py", line 40, in <module> result = student1.__marking(78) AttributeError: Student instance has no attribute '__marking'

Step 7.1 把变量变成私有 前面的实验把marking方法前面添加双下滑线'__' 之后,在类的外部读取是会报错的 在这里把score变量前面添加双下滑线'__' 之后,在类的外部读取是不会报错的,这是为什么呢? $ s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.__score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): if score < 0: return '不能打负分' self.__score = score print(self.name + '同学本次考试分数为:' + str(self.__score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) result = student1.marking(78) print(result) #student1.do_homework() student1.__score = -1 #print(student1.__score)

Step 7.2 把变量变成私有 前面说到私有变量是不可读取,不可赋值,但在这里可以正常赋值,并且可读取到双下滑线score的值,这是为什么呢? 并不是因为设置__score实例变量没有生效,而是因为python 动态语言的特性,student1.__score = -1 实际上给student1新添加了一个实例变量,python 是可以通过点'.'的方式添加一个新的实例变量 $ s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.__score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): if score < 0: return '不能打负分' self.__score = score print(self.name + '同学本次考试分数为:' + str(self.__score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) result = student1.marking(78) print(result) #student1.do_homework() student1.__score = -1 print(student1.__score) #执行结果 $ python s4.py 小明同学本次考试分数为:78 None -1
Step 7.3 实例化另外一个student2 student1 = Student('小明', 18)
student2 = Student('小芳', 18) //实例化另外一个student2
result = student1.marking(78)
student1.__score = -1
print(student1.__score)
print(student2.__score) //读取student2私有属性 执行结果是报错的,为什么读取student1.__score没有报错,但读取student2.__score却报错了. 原因在于有强行赋值的操作[student1.__score = -1],因为python 动态语言的特性,student1.__score = -1 实际上给student1新添加了一个实例变量,python 是可以通过点'.'的方式添加一个新的实例变量 $ vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.__score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): if score < 0: return '不能打负分' self.__score = score print(self.name + '同学本次考试分数为:' + str(self.__score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) student2 = Student('小芳', 18) //实例化另外一个student2 result = student1.marking(78) student1.__score = -1 print(student1.__score) print(student2.__score) //读取student2私有属性 #执行结果 $python s4.py 小明同学本次考试分数为:78 -1 Traceback (most recent call last): File "s4.py", line 47, in <module> print(student2.__score) AttributeError: Student instance has no attribute '__score'

Step 7.4 打印student1属性 在执行结果中可见到 '_Student__score' ,可没设置过这样变量;其实'_Student__score'变量,也就是我们设置的私有 self.__score = score,只不过python 在存储私有变量时会做一个更改,会自动把__score,更改为_Student__score 新的名称 在执行结果中还有一个'__score',是动态添加的 student1.__score = -1 为什么前面访问私有变量,报错提示找不到,因为python 把私有变量的名称改了. vim s4.py class Student(): sum = 1 def __init__(self, name, age): self.name = name self.age = age self.__score = 0 self.__class__.sum += 1 #print('当前班级学生总数为:' + str(self.__class__.sum )) def marking(self, score): if score < 0: return '不能打负分' self.__score = score print(self.name + '同学本次考试分数为:' + str(self.__score)) def do_homework(self): self.do_work() print('homework') def do_work(self): print() @classmethod def plus_sum(cls): cls.sum += 1 print(cls.sum) @staticmethod def add(x,y): print('This is a static method') student1 = Student('小明', 18) #student2 = Student('小芳', 18) result = student1.marking(78) student1.__score = -1 print(student1.__dict__) //打印类属性 #执行结果 $ python s4.py 小明同学本次考试分数为:78 {'age': 18, '_Student__score': 78, '__score': -1, 'name': '小明'}
热门排行