夜光序言:
再温柔平和宁静的落雨,也有把人浸透的威力。
正文:
5.1 类与对象
5.1.1 目标
虽然 Python 是解释性语言,但是它是面向对象的,能够进行对象编程。教学目标是掌握 Python 面向对象的规则,以个人信息为例,能够建立个人信息类与对象。
5.1.2 类与对象
在进行 python 面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义:
class className:
block
注意类名后面有个冒号,block 要向右边缩进,在 block 块里面就可以定义属性和方法了。
例 5-1-1:定义了一个 Person 类
class Person:
#定义了一个属性
name = 'james'
#定义了一个方法
def printName(self):
print self.name
Person 类定义完成之后就产生了一个全局的类对象,可以通过类对象来访问类中的属性和方法了。类定义好后就可以进行实例化操作,通过:
p=Person( )
这样就产生了一个Person的实例对象,实例对象时根据类的模版生成的一个内存实体,有确定的数据与内存地址。
5.1.3 类属性
例 5-1-2:类属性定义
class Person:
name = 'james'
age = 12
定义了一个 Person 类,里面定义了 name 和 age 属性,默认值分别为'james'和 12,其中的 name 与 age 就是类 Person 的属性,这种属性是定义在类中的,也称为类属性,可以通过下面的两钟方法来读取访问:
(1) 使用类的名称,例如 Person.name,Person.age;
(2) 使用类的实例对象,例如 p=Person()是对象,那么 p.name,p.age;
例 5-1-3:类属性访问
class Person:
name = 'james'
age = 12
p=Person()
print(Person.name,Person.age)
print(p.name,p.age)
结果:
james 12
james 12
类属性是与类绑定的,它是被这个类所拥有的,如果要修改类的属性就必须使用类名称
访问它,而不能使用对象实例访问它。
例 5-1-4:类属性访问与实例属性建立
class Person:
name = 'james'
age = 12
p=Person()
q=Person()
print(Person.name,Person.age)
print(p.name,p.age)
print(q.name,q.age)
Person.name="robert"
p.age=15
print(Person.name,Person.age)
print(p.name,p.age)
print(q.name,q.age)
结果:
james 12
james 12
james 12
robert 12
robert 15
robert 12
在程序中我们通过类的名称访问方法修改了 name 属性:
Person.name="robert"
那么后面的 p,q 对象实例访问到的 p.name,q.name 都是"robert"。但是我们通过类对象 p 修改 age 属性:
p.age=15
那么 Person.age,q.age 仍然是 12,还是原来的类属性 age 的值,只有 p.age 变成 15!这是怎么回事呢?原来在执行:
p.age=15
时访问的不是类属性 age,而是为 p 对象产生了一个 age 属性,即 p.age 是一个只与 p 对象绑定的属性,而不是类对象 Person.age。q 没有这样的新的 age 属性,q.age 还是类 Person的 age 属性。
Python 的这个功能特性很像 JavaScipt,实例有结合任何属性的功能,只要执行:
对象实例.属性=....
为这个对象实例赋值,那么如果该对象实例存在这个属性,这个属性的值就被改变,但是如果不存在该属性就会自动为该对象实例创建一个这样的属性。
5.1.4 访问的权限
前面 Person 中的 name 和 age 都是公有的,可以直接在类外通过对象名访问,如果想定义成私有的,则需在前面加 2 个下划线 ' __'。
例 5-1-5:访问权限
class Person:
__name = 'james'
__age = 12
def show():
print(Person.__name,Person.__age)
#print(Person.__name,Person.__age)
Person.show()
结果:
james 12
而语句:
print(Person.__name,Person.__age)
是错误的,提示找不到该属性,因为私有属性是不能够在类外通过对象名来进行访问的。在 Python 中没有像 C++中 public 和 private 这些关键字来区别公有属性和私有属性,它是以属性命名方式来区分,如果在属性名前面加了 2 个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了 2 个下划线的话表示该方法是私有的,否则为公有的)。
5.1.5 【案例】Person 类的属性
1、案例描述
编写个人信息类并建立对象访问属性。
2、案例分析
个人信息类 Person 定义如下:
class Person:
name="XXX"
gender="X"
age=0
其中 name,gender,age 都是类属性,类属性一般使用类名称 Person 访问。
3、案例代码
class Person:
name="XXX"
gender="X"
age=0
p=Person()
print(p.name,p.gender,p.age)
print(Person.name,Person.gender,Person.age)
p.name="A"
p.gender="Male"
p.age=20
Person.name="B"
Person.gender="Female"
Person.age=21
print(p.name,p.gender,p.age)
print(Person.name,Person.gender,Person.age)
结果:
XXX X 0
XXX X 0
A Male 20
B Female 21
由此可见通过对象 a 与 Person 类名称都可以读取到类属性 name、gender、age,但是改
写这些类属性时下列语句:
p.name="A"
p.gender="Male"
p.age=20
结果是为对象 p 生成了自己的 name、gender、age,属性,改写的不是类属性 name、gender、
age,,只有通过 Person 的下列语句:
Person.name="B"
Person.gender="Female"
Person.age=21
改写的才是 name、gender、age,类属性。