天天看点

python学习笔记13--类和对象

1. 类和对象简介

与C++和Java一样,python也支持面向对象编程(OOP)。一个对象代表真实世界中的一个实体,它包括identity、state、behavior。identity是对象的唯一编号,在运行过程中,python会自动地为每个对象分配唯一的身份识别编号;state也被叫做properties或attribute,它是对象特性的体现;behavior也被称作method,它用来返回对对象进行操作的结果。

对象与类的区别,类似于匹萨和匹萨食谱的区别,你可以用一个匹萨食谱(类)制造很多匹萨(对象),简单来说,对象是类的一个实例。

2. 类的定义

Python中通常用

class ClassName:

     initializer

     methods

来定义一个类。下面的代码定义了一个圆形类:

#coding=utf-8
import math

class Circle:
    # 构造函数
    def __init__(self,radius = 1):
        self.radius = radius
    
    # 返回圆的周长
    def getPerimeter(self):
        return 2 * self.radius * math.pi
    
    # 返回圆的面积
    def getArea(self):
        return self.radius * self.radius * math.pi
    
    # 设置圆的半径
    def setRadius(self,radius):
        self.radius = radius
        

# 创建两个圆对象,并用.访问属性和方法
c1 = Circle()
c2 = Circle(5)

# 第一个圆
print ("第一个圆的半径为", c1.radius, ",周长为",c1.getPerimeter(),
       ",面积为",c1.getArea())

# 第二个圆
print ("第二个圆的半径为", c2.radius, ",周长为",c2.getPerimeter(),
       ",面积为",c2.getArea())
           

1)initializer通常命名为__init__,这是个特殊的方法;

2)注意所有的方法,包括Initializer,都有第一个参数self,self参数是指向对象本身的,我们可以通过self.var来创建或修改类的属性变量,如其中的self.radius=radius,并且它的作用范围是整个类。

3)可以同dot操作符(.)来访问对象的属性域和方法函数,如c1.radius,c1.getArea();

3. 可改变对象与不可改变对象

之前了解到数字和字符串是不可改变对象,当不可改变对象作为参数传递给函数f时,在函数f内部的修改不会反映在原始函数中;可改变对象则相反,若将可改变对象传递给函数f,则在函数f中的修改会反映在原始函数中。举个例子:

def main():
    # 创建一个半径为1的圆
    myCircle = Circle()
    
    # 打印半径分别为1,2,3,4,5时的圆的面积
    n = 5
    printAreas(myCircle,n)
    
    print ("\nRadius is",myCircle.radius)   # 6
    print ("n is", n)                       # 5

def printAreas(c,times):
    print ("Radius \t\tArea")
    while times>=1:
        print (c.radius,"\t\t",c.getArea())
        c.radius += 1
        times -= 1

main()
           

可以看出,在将n=5传递给函数printAreas()后,n的值并没有改变,因为其是不可改变对象;而myCircle传递给函数printAreas()之前,其半径为1,而从函数结束后返回,其半径为6,说明myCircle在函数中的修改反映到了原始函数中,因为它是可改变对象。

4. 数据隐藏

上面的代码中,其他函数可以直接访问对象的属性变量,这样在编程时可能会出现难以维护的情形,所以有时候我们希望能避免直接的访问或修改属性变量,而通过getter和setter方法来操作属性变量,这就叫做数据隐藏(data hiding),也可以叫做私有变量,python中的私有变量用__var表示。同样,也可以用__methods定义私有方法。如修改Circle类中的radius为私有变量:

# 构造函数
    def __init__(self,radius = 1):
        self.__radius = radius
           

这样,如果直接访问该变量的话,会出现 'Circle' object has no attribute '__radius' 错误。

在面向过程编程中,数据和操作是分离的,并且需要将数据发送给操作方法;而面向对象编程中,数据和相关的操作被放在一起,构成一个对象,这种方法是真实世界的镜像,其中所有对象的属性和操作紧密结合;面向对象编程提高了软件的可重用性,并且使程序易于阅读和维护,效率较高。