在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。

  但是,从前面的Student类定义来看,外部代码还是可以自由地修改一个实例的name,score属性

>>> bart.score
59
>>> bart.score=99
>>> bart.score
99

  如果要让内部属性不被外部访问,可以把属性的名称前面加上两个下划线__,在python中,实例的变量名如果以__开头,就变成了私有变量(private),只有内部可以访问,外部不能访问

>>> class Student(object):
... def __init__(self,name,score):
... self.__name=name
... self.__score=score
... def print_score(self):
... print('%s:%s' %(self.__name,self.__score))
...
>>> bart=Student('Zhangsan',59)
>>> bart.__name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

  这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的包含,代码更加健壮

  如果外部代码想要获取name和score怎么办?可以给类Student增加get_name和get_score方法

class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def print_score(self):
print('%s:%s' %(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score

  通过bart.get_name()即可返回对应name

  如果又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法

class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def print_score(self):
print('%s:%s' %(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
self.__score=score

  set_score除了self还包含一个参数score修改方法为

bart.set_score(99)

  原先直接通过bart.score=99也可以直接修改,为什么要定义一个方法大费周折?因为在方法中,可以对参数进行检查,避免传入无效的参数

class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def print_score(self):
print('%s:%s' %(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
if 0<=score<=100:
self.__score=score
else:
raise ValueError('bad score')

  如果传递了无效的成绩会报错

Traceback (most recent call last):
File "Student.py", line 28, in <module>
bart.set_score(101)
File "Student.py", line 15, in set_score
raise ValueError('bad score')
ValueError: bad score

  注意,在python中,变量名类似__xxx___,也就是以双下划线开头并且以双下划线结尾的是特殊变量,特殊变量是可以直接访问的,不是private变量,所以不能用__name__,__score__这样的变量名。

  有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

  双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:

>>> bart._Student__name
'Zhangsan'

  但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。

  注意下面这种错误写法

>>> bart=Student('Zhangsan',59)
>>> bart.get_name()
'Zhangsan'
>>> bart.__name='Lisi'
>>> bart.__name
'Lisi'

  表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。不信试试:还是原来的Zhangsan

>>> bart.get_name()
'Zhangsan'

  练习:

class Student(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender

  

class Student(object):
def __init__(self,name,gender):
self.__name=name
self.__gender=gender
def get_gender(self):
return self.__gender
def set_gender(self,gender):
if gender == 'male' or gender == 'female':
self.__gender=gender
else:
raise ValueError('bad gender性别为male或者female')
bart=Student('Zhangsan','male')
print(bart.get_gender())
bart.set_gender('femalde')
print(bart.get_gender())

  如果传递的性别参数不是male或者female则报错

Traceback (most recent call last):
File "Student2.py", line 14, in <module>
bart.set_gender('femalde')
File "Student2.py", line 11, in set_gender
raise ValueError('bad gender性别为male或者female')
ValueError: bad gender性别为male或者female

  

Python3之类和实例访问限制的更多相关文章

  1. SQL ser 跨实例访问数据库

    SqlServer如何跨实例访问数据库 Exec sp_droplinkedsrvlogin LinkName,NullExec sp_dropserver LinkName go EXEC sp_a ...

  2. static成员是可以被其所在class创建的实例访问!!!

    <span style="font-family: Arial, Helvetica, sans-serif; ">关于静态方法以及静态变量的使用就不详细的说了,我就这 ...

  3. Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的

    转:http://www.cnblogs.com/2gua/ Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法 ...

  4. 通过FEDERATED存储引擎跨实例访问数据

    通过FEDERATED存储引擎同步两实例间的表数据需求情景:实例1中A库中的三个视图是实例2中的B库所依赖的,B需要A库中三个视图的实时数据.方案:通过FEDERATED来完成跨势力的查询FEDERA ...

  5. Python3 的urllib实例

    在Python3中合并了 urllib 和 urllib2, 统一命名为 urllib 了,我觉得这样更加合理了.让我们可以像读取本地文件一样读取WEB上的数据.封装了一个类,供以后方便使用吧!并附带 ...

  6. Python学习 Day 7 面向对象 类和实例 访问限制

    面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程 ...

  7. Python3面向对象编程实例

    /*认真研究完这个实例,理解python面向对象编程的方法*/class Person: """人员信息""" # 姓名(共有属性) nam ...

  8. python3类和实例

    面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...

  9. Python3之类和实例

    面向对象的重要概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如学生类Student,而实例是根据类创建出来的一个个具体的对象,每个对象都拥有相同的方法,单各自的数据可能 ...

随机推荐

  1. 1. let与const

    1.ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. var a = []; for (var i = 0;i<10;i++) ...

  2. [ARIA] Accessible animations with reduced motion

    Animations can make people sick, or worse! By adding animation toggles and listening in to the user' ...

  3. Define Interfaces and Share Class Members through Mixins in Dart

    In this lesson, we will cover Interfaces and Mixins. Interfaces act as a contract containing propert ...

  4. [English] - 单词阶段1

    百词斩这个app很好玩,尤其是在记忆单词的时候,效果显著. 有的PK赛场也是比较谁的单词翻译提交的快,这个我曾经连胜好几次.

  5. 【概率论】5-1:分布介绍(Special Distribution Introduction)

    title: [概率论]5-1:分布介绍(Special Distribution Introduction) categories: - Mathematic - Probability keywo ...

  6. [报错解决] "MySQL server has gone away" 解决思路

    大概的4个思路 1.超时,超时的阀值有wait_timeout这个参数控制 2.连接被人为的kill 3.发送的SQL语句过大超过max_allowed_packet的大小. (操作的sql语句太长了 ...

  7. python对象调用父类的方法

    #类定义 class People: #定义基本属性 name = '' age = 0 #定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 #定义构造方法 def __ini ...

  8. luogu P4168 蒲公英+ 分块学习笔记

    传送门 题目描述 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列\((a_1,a_2..a_n)\),其中 \(a_i\)为一 ...

  9. Android中View大小的确定过程

    View and ViewGroup 安卓中有5种基本的 ViewGroup: FrameLayout RelativeLayout LinearLayout TableLayout Absolute ...

  10. 异步任务神器 和定时任务Celery

    异步任务神器 Celery Celery 在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避免它们阻塞主程序的运行,我们经常会采用多线程或异步任务.比如,在 Web 开发中,对新用户的注册 ...