《Python 编程从入门到实践》———— 创建和使用类

创建类

 面向对象技术简介

  1. 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  2. 方法:类中定义的函数。
  3. 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  4. 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  5. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  6. 局部变量:定义在方法中的变量,只作用于当前实例的类。
  7. 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
  8. 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
  9. 实例化:创建一个类的实例,类的具体对象。
  10. 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

 和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。Python 中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。对象可以包含任意数量和类型的数据。


 根据约定,在 Python 中,首字母大写的名称指的是类。这个类定义中的括号是空的,因为我们要从空白创建这个类。类中的函数称为方法; 你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。方法 init() 是一个特殊的方法,每当你根据 person 类创建新实例时,Python 都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免 Python 默认方法与普通方法发生名称冲突。


 在 init() 方法的定义中,形参 self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包含形参self呢?因为 Python 调用这个__init__() 方法来创建 first_person 实例时,将自动传入实参 self。每个与类相关联的方法调用都自动传递实参 self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。我们创建 first_person 实例时,Python 将调用 person类的方法__init__()。我们将通过实参向 person 传递名字、年龄和性别;self 会自动传递,因此我们不需要传递它。每当我们根据 person 类创建实例时,都只需给最后三个形参(name、age 和 sex)提供值。


 定义的变量都有前缀 self。以 self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。self.name = name 获取存储在形参 name 中的值,并将其存储到变量 name 中,然后该变量被关联到当前创建的实例。像这样可通过实例访问的变量称为属性




 下面是一个创建好的实例。

# 输入
class person(object): # Creat person class including name, age, sex
    def __init__(self,name,age,sex):   # input related info 
        self.name = name
        self.age = age
        self.sex = sex
    def get_age(self):              # get person age
        print(self.name.title() + "'s age is " + " " + str(self.age))
    def get_sex(self):              # get person sex
        print(self.name.title() + "'s sex is " + " " + self.sex)

    
first_person = person('tom','80','male')
second_persion = person('jerry','82','femal')
first_person.get_age()
second_person.get_sex()


# 输出
Tom's age is  80
Jerry's sex is  femal

1. 访问属性
 要访问实例的属性,可使用句点表示法。句点表示法在 Python 中很常用,这种语法演示了Python如何获悉属性的值。在这里,Python 先找到实例 first_person,再查找与这个实例相关联的属性name。在 person 类中引用这个属性时,使用的是self.name。
2. 调用方法
 根据 person 类创建实例后,就可以使用句点表示法来调用 person 类中定义的任何方法。要调用方法,可指定实例的名称(这里是 first_person)和要调用的方法,并用句点分隔它们。遇到代码 first_person.get_age() 时,Python 在类 person 中查找方法 get_age() 并运行其代码。这种语法很有用。如果给属性和方法指定了合适的描述性名称,如name、age、sit()和roll_over(),即便是从未见过的代码块,我们也能够轻松地推断出它是做什么的。
3. 创建多个实例
 可按需求根据类创建任意数量的实例。就算我们给第二个人指定同样的名字和年龄,Python依然会根据 person 类创建另一个实例。你可按需求根据一个类创建任意数量的实例,条件是将每个实例都存储在不同的变量中,或占用列表或字典的不同位置。



















使用类

 你可以使用类来模拟现实世界中的很多情景。类编写好后,你的大部分时间都将花在使用根据类创建的实例上。你需要执行的一个重要任务是修改实例的属性。你可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认值时,在方法__init__() 内指定这种初始值是可行的;如果你对某个属性这样做了,就无需包含为它提供初始值的形参。

# 输入
class Car(object):
    def __init__(self,band,model,year):
        self.band = band
        self.model = model
        self.year = year
        self.mile = 300

    def get_info(self):
        print(
            "My car is " + self.band.title() + " "
            + self.model + " and bought in " + str(self.year))

    def report_odometer(self):
        print("The mile drving is " + str(self.mile))

my_car = Car("BWM",'I8',2020)
my_car.report_odometer()

# 输出
The mile drving is 300

 在实际的过程中,我们的汽车行驶里程是时刻变化的,所以我们在执行程序的过程中,存在修改属性值的情况。这里介绍一下如果修改属性值。
  1. 直接修改属性的值
  要修改属性的值,最简单的方式是通过实例直接访问它。有时候需要像这样直接访问属性,但其他时候需要编写对属性进行更新的方法。

# 输入
class Car(object):
    def __init__(self,band,model,year):
        self.band = band
        self.model = model
        self.year = year
        self.odometer = 0

    def getinfo(self):
        print("my car is " + self.band + " " + self.model + " and is bought in " + str(self.year))

    def reportinfo(self):
        print("The odometer is " + str(self.odometer))


my_car = Car("BWM","I8",2021)
my_car.getinfo()
my_car.odometer = 300
my_car.reportinfo()

# 输出
my car is BWM I8 and is bought in 2021
The odometer is 300

  2. 通过方法修改属性的值
  如果有替你更新属性的方法,将大有裨益。这样,你就无需直接访问属性,而可将值传递给一个方法,由它在内部进行更新。对Car类所做的唯一修改是在处添加了方法update_odometer()。这个方法接受一个里程值,并将其存储到 self.odometer_reading 中。我们调用了update_odometer(),并向它提供了实参。

# 输入
class Car(object):
    def __init__(self,band,model,year):
        self.band = band
        self.model = model
        self.year = year

    def getinfo(self):
        print("my car is " + self.band + " " + self.model + "and is bought in " + str(self.year))

    def reportmileinfo(self,odometer):
        self.odometer = odometer
        print("The odometer is " + str(self.odometer))


my_car = Car("BWM","I8",2021)
my_car.reportmileinfo(230)

# 输出
The odometer is 230

  3. 通过方法对属性的值进行递增
  有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手车,且从购买到登记期间增加了 100 英里的里程,下面的方法让我们能够传递这个增量,并相应地增加里程表读数。你可以使用类似于上面的方法来控制用户修改属性值(如里程表读数)的方式,但能够访问程序的人都可以通过直接访问属性来将里程表修改为任何值。要确保安全,除了进行类似于前面的基本检查外,还需特别注意细节。

# 输入
class Car(object):
    def __init__(self,band,model,year):
        self.band = band
        self.model = model
        self.year = year
        self.odometer = 100

    def getinfo(self):
        print("my car is " + self.band + " " + self.model + "and is bought in " + str(self.year))

    def reportmileinfo(self,odometer):
        self.odometer += odometer
        print("The odometer is " + str(self.odometer))


my_car = Car("BWM","I8",2021)
my_car.reportmileinfo(230)

# 输出
The odometer is 330

私有性
  1. 类的私有属性
  __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

# 输入
class Car(object):
    __username = "Youth"

    def __init__(self,band):
        self.band = band

    def printband(self):
        print(self.band)

mycar = Car("Adui")
print(mycar.band)
print(mycar.__username)


# 输出
Adui
Traceback (most recent call last):
  File "C:/script/Class2.py", line 12, in <module>
    print(mycar.__username)
AttributeError: 'Car' object has no attribute '__username'

  2. 类的私有方法
  __private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。

# 输入
class Car(object):
    def __init__(self,band):
        self.band = band
        

    def printband(self):
        print(self.band)

    def __printage(self):
        print(str(24))

mycar = Car("Adui")
mycar.printband()
mycar.__printage()

# 输出
Adui
Traceback (most recent call last):
  File "C:/script/Class2.py", line 14, in <module>
    mycar.__printage()
AttributeError: 'Car' object has no attribute '__printage'
类的专有方法
Name Description
__init__ 构造函数,在生成对象时调用
__del__ 析构函数,释放对象时使用
__repr__ 打印,转换
__setitem__ 按照索引赋值
__getitem__ 按照索引获取值
__len__ 获得长度
__cmp__ 比较运算
__call__ 函数调用
__add__ 加运算
__sub__ 减运算
__mul__ 乘运算
__truediv__ 除运算
__mod__ 求余运算
__pow__ 乘方

猜你喜欢

转载自blog.csdn.net/qq_42957717/article/details/118083684