Python -- 面向对象编程、类和实例、访问限制

面向对象编程

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

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

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

类Class:

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

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

对象的方法(Method)

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



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

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

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


类和实例

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

定义类,Class关键字

(1) 关键字class

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

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

创建实例:类名+()

1 #这是最简单的定义类
2 class Student(object):
3     pass
4
5 #创建一个实例
6 bart=Student()
7 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参数


数据封装

类的方法

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

实战

 1 class Student(object):
 2
 3     def __init__(self, name, score):
 4         self.name = name
 5         self.score = score
 6
 7     def print_score(self):
 8         print(‘%s: %s‘ % (self.name, self.score))
 9
10     def get_grade(self):
11         if self.score >= 90:
12             return ‘A‘
13         elif self.score >= 60:
14             return ‘B‘
15         else:
16             return ‘C‘
17
18 bart = Student(‘Bart Simpson‘, 59)
19 lisa = Student(‘Lisa Simpson‘, 87)
20
21 print(‘bart.name =‘, bart.name)
22 print(‘bart.score =‘, bart.score)
23 bart.print_score()
24
25 print(‘grade of Bart:‘, bart.get_grade())
26 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个下划线的代码:

 1 class Student(object):
 2
 3     def __init__(self, name, score):
 4         self._name = name
 5         self._score = score
 6
 7     def print_score(self):
 8         print(‘Print语句返回值:%s: %s‘ % (self._name, self._score))
 9
10
11 bart=Student(‘bart simpon‘,98)
12
13 print("这是1个下划线的私有变量:")
14 bart.score=45
15 print("bart.score:",bart.score)
16 print("bart.print_score():",bart.print_score())
17 print("")
18
19
20 bart.__score=45
21 print("bart.__score:",bart.__score)
22 print("bart.print_score():",bart.print_score())
23 print("")
24
25
26 bart._Student_score=45
27 print("bart._Student_score:",bart._Student_score)
28 print("bart.print_score():",bart.print_score())
29 print("")
30
31
32 bart._Student__score=45
33 print("bart._Student__score:",bart._Student__score)
34 print("bart.print_score():",bart.print_score())
35 print("")
36
37 bart._score=45
38 print("bart._score:",bart._score)
39 print("bart.print_score():",bart.print_score())

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

2个下划线的代码:

 1 class Student(object):
 2
 3     def __init__(self, name, score):
 4         self.__name = name
 5         self.__score = score
 6
 7     def print_score(self):
 8         print(‘Print语句返回值:%s: %s‘ % (self.__name, self.__score))
 9
10
11
12
13 bart=Student(‘bart simpon‘,98)
14 # print("gds",bart.print_score())
15 print("这是2个下划线的私有变量:")
16 bart.score=45
17 print("bart.score:",bart.score)
18 print("bart.print_score():",bart.print_score())
19 print("")
20
21
22 bart._score=45
23 print("bart._score:",bart._score)
24 print("bart.print_score():",bart.print_score())
25 print("")
26
27
28 bart.__score=45
29 print("bart.__score:",bart.__score)
30 print("bart.print_score():",bart.print_score())
31 print("")
32
33
34 bart._Student_score=45
35 print("bart._Student_score:",bart._Student_score)
36 print("bart.print_score():",bart.print_score())
37 print("")
38
39
40 bart._Student__score=45
41 print("bart._Student__score:",bart._Student__score)
42 print("bart.print_score():",bart.print_score())

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

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

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

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

如果外部代码要修改score怎么办?可以给Student类增加get_score方法。

代码如下:

 1 class Student(object):
 2
 3     def __init__(self, name, score):
 4         self.__name = name
 5         self.__score = score
 6
 7     def print_score(self):
 8         print(‘%s: %s‘ % (self.__name, self.__score))
 9
10     def get_name(self):
11         return self.__name
12
13     def get_score(self):
14         return self.__score
15
16     def set_score(self, score): #使用这种方法修改属性值,可以检查传入的参数值是否有问题
17         if 0 <= score <= 100:
18             self.__score = score
19         else:
20             raise ValueError(‘bad score‘)
21
22 bart = Student(‘Bart Simpson‘, 59)
23 print("bart._Student__score:",bart._Student__score)  #这种就运行正确了
24
25 print("bart.get_score():",bart.get_score())
26
27 print(bart.score)  #运行结果出错,提示‘Student‘ object has no attribute ‘score‘
28
29 # 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

原文地址:https://www.cnblogs.com/bravesunforever/p/10742250.html

时间: 2024-11-10 03:17:11

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

Python 面向对象编程——类和实例

1        面向对象编程 面向对象编程: 面向对象编程--Object OrientedProgramming OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度. 面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消

Python 面向对象编程基础——初始化实例、类属性、方法

#1.初始化实例化属性.#可接受任意关键字参数,并把他们都作为属性赋值给实例.使用**kw,除了可以直接使用self.name = 'xxx'设置一个属性外,还可以通过setattr(self, 'name', 'xxx')设置属性.class Person(object):    def __init__(self, name, gender, **kw):        self.name = name        self.gender = gender        for k,v i

python学习day11 面向对象编程 类和实例

class Student(object): #class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的.通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类. def __init__(self,name,score): #通过定义一个特殊的__init__方法,在创建实例的时候,就把类的name,score等属性绑上去,__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__

【Python】[面向对象编程] 类和实例

1.注:必须牢记类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”2.定义类通过class 关键字:class 后面跟着类名,类名通常都是大写开头,接着是(object),表示类是从哪里继承俩的,所有类都继承 自object. class Student(object): pass 3.通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去: class Student(object): def __init__(self, name, scor

(转)Python 面向对象编程(一)

Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程.下面就来了解一下如何在Python中进行对象编程. 一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class className: block 注意类名后面有个冒号,在block块里面就可以定义属性和方法了.当一个类定义完之后,就产生了一个类对象.类对象支持

python 面向对象编程(一)

一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class className: block 注意类名后面有个冒号,在block块里面就可以定义属性和方法了.当一个类定义完之后,就产生了一个类对象.类对象支持两种操作:引用和实例化.引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称作实例对象.比如定义了一个people类: cl

Python面向对象编程总结(上)

在我学习python之前一直认为python是脚本型语言,不能用面相对象的方法进行编程,当我学习了python之后我发现我错了,python不但支持面相对象而且使用的人还挺多的.我从接触编程开始就是学习的Java语言,所以面相对象编程的思想在我的脑海里根深蒂固,让我一下从面向对象编程转换到面向过程编程还有一些不适应呢,所以我就来总结一下python面向对象编程的方法和过程.我将按照面向对象的构成要素来分析,依次为类和实例.属性.方法.封装.继承.多态,如果有什么问题还请大家积极指出,我所用的版本

python面向对象编程(OOP)

python作为一种解释性语言,其主要的编程方式就是面向对象,而且python的框架django也是主要面向对象的编程. 类(class)和对象(object) 类(class)是用来描述具有相同属性(attribute)和方法(method)对象的集合.对象(object)是类(class)的实例.比如学生都有名字和分数,他们有着共同的属性.这时我们就可以设计一个学生类,用来记录学生的名字和分数,并自定义打印出来. 属性(attribute):类里面用于描述所有对象共同特征的变量或数据.比如此

python面向对象编程进阶

python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(object): 2 pass 3 4 obj = Foo() 5 6 isinstance(obj, Foo) issubclass(sub, super)检查sub类是否是 super 类的派生类 1 class Foo(object): 2 pass 3 4 class B

只能通过类而不能通过类的实例访问常量属性

1.静态属性.静态方法 在面向对象编程中,我们不仅可以通过对象访问方法和属性,还可以通过类来访问它们.这样的方法和属性就是“静态的”(static),必须用static关键字来声明. [php] view plaincopyprint? class staticExample { staticpublic $num = 0; staticpublic function sayNum() { echoself::num; } } 静态方法是以类作为作用域的函数.静态方法不能访问这个类中的普通属性,