面向对象编程

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

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

类Class:

类是对象的模板。即类是对一组有相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述一组对象的共同属性和行为。

类是在对象之上的抽象,对象则是类的具体化,是类的实例。类可有其子类,也可有其它类,形成类层次结构。

任何类最终都可以追溯到根类object

对象的方法(Method)

给对象发消息实际上就是调用对象对应的关联函数,称之为对象的方法(Method).


综上,面向对象的设计思想是抽象出Class,根据Class创建Instance。

面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。

面向对象的三大特点:数据封装、继承、多态


类和实例

类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

定义类,Class关键字

(1) 关键字class

(2) 类名:通常是大写开头的单词,如Student

(3)(继承类):表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就是用object类,这是所有类最终都会继承的类。

注:当我们定义一个class的时候,实际上就定义了一种数据类型。定义的class数据类型和Python自带的数据类型没什么区别,比如str, dict, list。

创建实例:类名+()

 #这是最简单的定义类
class Student(object):
pass #创建一个实例
bart=Student()
print(bart)

运行结果:

<__main__.Student object at 0x00000000010CC2E8>,变量bart指向Student的一个实例,后面的0x00000000010CC2E8是内存地址,每个object的地址都不一样。

__init__方法

作用:绑定属性

注意:特殊方法“__init__”前后分别有两个下划线!!!

1,__init__方法的第一个参数永远是self,表示创建的实例本身,在__init__方法内部,把各种属性绑定到self

2,有了__init__方法,在创建实例的时候,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。


和普通函数相比,在类中定义的函数(不仅仅是__init__函数,包括后面类的方法函数,是指类中所有的定义函数),第一个参数永远是实例变量self,并且调用时,不用传递self参数


数据封装

类的方法

在类的内部定义访问数据的函数,这样,就把“数据”给封装起来了,这些封装数据的函数是和类本身关联起来的,称为类的方法。

实战

 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_grade(self):
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C' bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87) print('bart.name =', bart.name)
print('bart.score =', bart.score)
bart.print_score() print('grade of Bart:', bart.get_grade())
print('grade of Lisa:', lisa.get_grade())

运行结果:

变量名

特殊变量:以双下划线开头,并且以双下划线结尾的,是特殊变量,类似__xxx__,特殊变量是可以直接访问的,不是Private变量,所以,在需要特殊变量的地方不能用__name__、__score__这样的变量名。

私有变量(Private):有2种形式,一个下划线开头,两个下划线开头

(1) 一个下划线开头:如_name

这样的实例变量,外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思是:“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问。”

(2)两个下划线开头:如__name

双下划线开头的实例变量是不是一定不能从外部访问呢?

答:也不是,不能直接访问__name,是因为python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。

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

总的来说,Python本身没有任何机制阻止你干坏事,一切全靠自觉。


访问私有变量(Private)的方式:

举例:

bart=Student('bart simpon',98)
备注:空白处相当于新增变量,不会改变score的值 1个下划线 2个下划线
bart.score    
bart._score 可以访问  
bart.__score    
bart._Student_score    
bart._Student__score   可以访问

备注:1,空白处相当于新增变量,不会改变score的值

2,可以访问,说明我们可以修改私有变量的值

3,既然已经设置成私有变量了,应尽量不要随意访问


访问私有变量方式代码实践:

1个下划线的代码:

 class Student(object):

     def __init__(self, name, score):
self._name = name
self._score = score def print_score(self):
print('Print语句返回值:%s: %s' % (self._name, self._score)) bart=Student('bart simpon',98) print("这是1个下划线的私有变量:")
bart.score=45
print("bart.score:",bart.score)
print("bart.print_score():",bart.print_score())
print("") bart.__score=45
print("bart.__score:",bart.__score)
print("bart.print_score():",bart.print_score())
print("") bart._Student_score=45
print("bart._Student_score:",bart._Student_score)
print("bart.print_score():",bart.print_score())
print("") bart._Student__score=45
print("bart._Student__score:",bart._Student__score)
print("bart.print_score():",bart.print_score())
print("") bart._score=45
print("bart._score:",bart._score)
print("bart.print_score():",bart.print_score())

一个下划线:   只有bart._score能修改_score的值

2个下划线的代码:

 class Student(object):

     def __init__(self, name, score):
self.__name = name
self.__score = score def print_score(self):
print('Print语句返回值:%s: %s' % (self.__name, self.__score)) bart=Student('bart simpon',98)
# print("gds",bart.print_score())
print("这是2个下划线的私有变量:")
bart.score=45
print("bart.score:",bart.score)
print("bart.print_score():",bart.print_score())
print("") bart._score=45
print("bart._score:",bart._score)
print("bart.print_score():",bart.print_score())
print("") bart.__score=45
print("bart.__score:",bart.__score)
print("bart.print_score():",bart.print_score())
print("") bart._Student_score=45
print("bart._Student_score:",bart._Student_score)
print("bart.print_score():",bart.print_score())
print("") bart._Student__score=45
print("bart._Student__score:",bart._Student__score)
print("bart.print_score():",bart.print_score())

2个下划线:  只有bart._Student__score能修改__score的值

如果要使内部属性不被外部访问,可以在属性名前加两个下划线__,变成私有变量,只有内部可以访问,外部不能访问。

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

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

如果外部代码要修改score怎么办?可以给Student类增加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 def set_score(self, score): #使用这种方法修改属性值,可以检查传入的参数值是否有问题
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score') bart = Student('Bart Simpson', 59)
print("bart._Student__score:",bart._Student__score) #这种就运行正确了 print("bart.get_score():",bart.get_score()) print(bart.score) #运行结果出错,提示'Student' object has no attribute 'score' # print(bart.__score) #运行结果出错,提示'Student' object has no attribute '__score'

运行结果:

问题:为什么一个、两个下划线的地方,print( bart.score )能运行出结果,而这最近的一段代码中print( bart.score )却报错?

答:前者是相当于新增加了一个变量,所以能运行出结果,而后者的print( bart.score )这种访问形式是不能直接访问私有变量,所以报错,而print( bart._Student__score )却访问成功了

参考网址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

Python面向对象编程 -- 类和实例、访问限制的更多相关文章

  1. python基础编程——类和实例

    在了解类和实例之前,需要先了解什么是面向对象,什么又是面向过程.面向过程是以过程为中心实现一步步操作(相互调用,类似流水线思想):面向对象是以事物为中心,某个事物可以拥有自己的多个行为,而另一个事物也 ...

  2. Python实用笔记 (18)面向对象编程——类和实例

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

  3. Python面向对象:类、实例与访问限制

    首先记录下面向对象的名词: 对象:python万物皆对象,程序设计的东西在对象上体现. 类:具有相同属性和行为的对象的集合. 消息:各个对象之间通过消息相互联系. 方法:对象功能实现的过程. 封装:把 ...

  4. python学习笔记1 -- 面向对象编程类和实例

    由于之前有一定基础,所以python中的类的概接受的比较快,与其他语言一样, python也是通过类来进行事务的抽象,一切皆对象,要不然怎么说程序员不缺对象呢. 言归正传,python中类的声明是cl ...

  5. Python - 面向对象编程 - 类变量、实例变量/类属性、实例属性

    什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html 什么是 Python 类.类对象.实例对象 https://www.cnblogs.com ...

  6. Python 面向对象编程——类定义与对象

    <类定义与对象声明> 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对 ...

  7. python -- 面向对象编程(类、对象)

    一.类 类是用来描述具有相同的属性和方法的对象的集合. 它定义了该集合中每个对象共同拥有的属性和方法. 类是一个独立的单位,它有一个类名,其内部包括成员变量和成员方法,分别用于描述对象的属性和行为. ...

  8. Python面向对象编程-类的封装,继承、多态

    面向对象是一种程序设计思想,对象作为程序基本单元,包含了数据和操作数据的函数. 面向对象的三大特点--数据封装.多态和继承. #类的创建,class关键字,类名大写,object表示从哪个类继承而来, ...

  9. python 面向对象二 类和实例

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

随机推荐

  1. 【ASP.NET Core】在CentOS上安装.NET Core运行时、部署到CentOS

    第一步:Add the dotnet product feed sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc ...

  2. The Non-Inverting Amplifier Output Resistance by Adrian S. Nastase [转载]

    Source Address: http://masteringelectronicsdesign.com/the-non-inverting-amplifier-output-resistance/ ...

  3. 重谈react优势——react技术栈回顾

    react刚刚推出的时候,讲react优势搜索结果是几十页. 现在,react已经慢慢退火,该用用react技术栈的已经使用上,填过多少坑,加过多少班,血泪控诉也不下千文. 今天,再谈一遍react优 ...

  4. 使用vscode调试小段的typescript代码

    最近在学习typescript.学习 嘛,当然免不了各种练习,试错.那么使用vscode就可以很方便的做到. 首先是安装node.js.我们知道,node.js提供了js脱离浏览器的执行平台.node ...

  5. day20 python常用模块

    认识模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀.     但其实import加载的模块分为四个通用类别: 1 使用pytho ...

  6. 比NGINX更快:nginx-1.15.5 vs mongols-1.2.3

    nginx是多进程web服务器的优秀代表. 本文要用mongols-1.2.3实现一个比nginx更快的多进程的web服务器. mongols是C++ 服务器基础设施库, 它的主要特性如下: tcp ...

  7. Delphi中Move、CopyMemory操作

    字串转字节数组 一.CopyMemory var s:PAnsiChar; ary:TArray<Byte>; bt:Byte; begin s:='Form Delphi'; SetLe ...

  8. Hibernate的工作原理及使用的原因

    一.工作原理: 1.读取并解析配置 2.读取并解析映射信息,创建Session Factory 3.打开Session 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Sess ...

  9. 从后台拿到echarts的数据值,求出百分比

    从后台拿到数据是一个数组的格式 例: var arr = [6,4,0,0,0,0,0,0]; 后来得到新的需求,需要鼠标移入的时候提示数量和百分比,数量本身就可以拿到, 求百分比的时候:先拿到数组最 ...

  10. IP通信基础学习第八周

    安装完华三模拟器,拖多台设备到工作区,全部启动及配置,建立好拓扑图,之后启动命令行终端. 配置登录用户,口令的指令有: <H3C>                       //用户直行 ...