Python编程:类

1.创建和使用类

         使用类几乎可以模拟任何东西。下面会编写一个简单的Dog类。

1.1创建Dog类

         根据Dog类创建的每个实例都会存储名字和年龄,并且我们还赋予了每条小狗蹲下和打滚的能力。

class Dog:
    """一次模拟小狗的简单尝试"""

    def __init__(self, name, age):
        """初始化属性name和age"""
        self.name = name
        self.age = age

    def sit(self):
        """模拟小狗收到命令时蹲下"""
        print(f"{self.name} is now sitting!")

    def roll_over(self):
        """模拟小狗收到命令式打滚"""
        print(f"{self.name} rolled over!")

        首先,使用语句class创建一个名为Dog的类,在Python中首字母大写表示的是类。之后,文档字符串对该类进行了简单的阐述。其次,使用了方法_init_()(在类中的函数成为方法),要注意,在开头和结尾处必须加上下划线,不然,你使用这个类来创建实例时,Python不会自动调用这个方法。我们将方法_init_()定义包括3个形参,要注意,一定要把self形参放在第一位,因为它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。所以,每当用Dog类创建实例时,都只需要给后面几个形参提供值。

1.2根据类创建实例

        根据上面的代码段,我们可以创建一个小狗的实例。

class Dog:
    """一次模拟小狗的简单尝试"""

    def __init__(self, name, age):
        """初始化属性name和age"""
        self.name = name
        self.age = age

    def sit(self):
        """模拟小狗收到命令时蹲下"""
        print(f"{self.name} is now sitting!")

    def roll_over(self):
        """模拟小狗收到命令式打滚"""
        print(f"{self.name} rolled over!")

my_dog = Dog('willie', 6)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old. ")
my_dog.sit()
my_dog.roll_over()

         注意,在类中定义的方法中,形参self在调用时是不用提供实参值。并且,在这里,命名约定很有作用,我们通常认为首字母大写的名称指的是类,首字母小写的名称指的是根据类创建的实例。

1.2.1访问属性

        要访问实例的属性,可以使用句点表示法。如下:

my_dog.name
my_dog.age

1.2.2调用方法

        创建实例后就可以使用句点表示法来调用Dog类中定义的任何方法了。如下:

my_dog.sit()
my_dig.roll_over()

1.2.3创建多个实例

        也可以按照要求创建多个实例。如下:

my_dog = Dog('willie', 6)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old. ")
my_dog.sit()
my_dog.roll_over()

your_dog = Dog('Lucy', 3)
print(f"\nYour dog's name is {your_dog.name}.")
print(f"Your dog is {your_dog.age} years old. ")
your_dog.sit()
your_dog.roll_over()

        注意,你要将每个实例都存储在不同的变量中,或者占用列表和字典的不同位置。

2.使用类和实例

          当你创建好一个类时,你可以直接修改类的属性,也可以编写方法以特定的方式进行修改。

2.1Car类

        下面编写了一个表示汽车的类,它存储了汽车的有关信息。

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())

2.2给属性指定默认值

        创建实例时,有些属性无需通过形参来定义,可在方法_init_()中为其指定默认值。

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

    def read_odometer(self):
        """打印一条指出汽车里程的信息"""
        print(f"This car has {self.odometer_reading}miles on it.")

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

        在定义_init_方法中,直接定义了self.odometer_reading,并且给它赋默认值为0。

2.3修改默认值

         我们能以三种方式修改属性的值:直接通过实例进行修改,通过方法进行设置,通过方法进行递增。

2.3.1直接修改属性的值

         要修改属性的值,最简单的方法就是通过实例直接访问它。如下段代码就是使用句点表示法直接访问并设置汽车的属性。

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

2.3.2通过方法修改属性的值

       可以通过方法修改属性的值,即可以将值传递给方法,由它在内部进行更新。

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

    def read_odometer(self):
        """打印一条指出汽车里程的信息"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self, mileage):
        """将里程表读数设置成指定的值"""
        self.odometer_reading = mileage

my_new_car = Car('audi', 'a4', 2019)
my_new_car.update_odometer(23)
my_new_car.read_odometer()

        通过在类的定义中,定义一个新的方法,用以修改odometer_reading的值。当然,还可以对update_odometer()方法进行扩展,使其在修改里程表读数时做一些额外的操作。

    def update_odometer(self, mileage):
        """将里程表读数设置成指定的值,并禁止里程表往回调"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer.")

2.3.3通过方法对属性的值进行递增

        有时候需要将属性的值进行递增,而不是给属性指定一个全新的值。可按如下代码操作:

    def increment_odometer(self, miles):
        """将里程表增加指定的量"""
        self.odometer_reading += miles

3.继承

        编写类时,并非总是要从空白开始。如果要编写的类是另外一个类的特殊版本,可以使用继承。一个类继承另外一个类时,可以继承另外一个类的所有属性和方法。原有的类称之为父类,新定义的类称之为子类。子类继承了父类所有的属性和方法,并且它还可以定义自己的属性和方法。

3.1子类的方法_init_()

             在既有类的基础上编写新类时,通常要调用父类的方法_init_()。这将初始化在父类方法_init_()中定义的所有属性,从而让子类包含这些属性。下段代码将模拟电动汽车。    

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

    def read_odometer(self):
        """打印一条指出汽车里程的信息"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self, mileage):
        """将里程表读数设置成指定的值,并禁止里程表往回调"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer.")

    def increment_odometer(self, miles):
        """将里程表增加指定的量"""
        self.odometer_reading += miles

class ElectricCar(Car):
    """电瓶车的独特之处"""

    def __init__(self, make, model, year):
        """初始化父类属性"""
        super().__init__(make, model, year)

my_tesla = ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())

         首先,定义了父类Car,创建子类时,父类必须包含在当前文件夹中,且位于子类的前面。定义子类时,必须在圆括号内指定父类的名称。其次,要使用super()这个特殊函数,让你能够调用父类的方法。

3.2给子类定义属性和方法

        让一个类继承另一个类后,就可以添加区分子类和父类的新属性和新方法了。下面代码中九条加了一个新的属性和方法。

class ElectricCar(Car):
    """电瓶车的独特之处"""

    def __init__(self, make, model, year):
        """初始化父类属性"""
        super().__init__(make, model, year)
        self.battery = 75

    def describe_battery(self):
        """打印一条描述电瓶容量的信息"""
        print(f"This car has a {self.battery}-kwh battery")

my_tesla = ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

        该段代码中,在_init_()方法中定义了新的属性,并赋予了75的默认值。这个属性是电动汽车这个新类特有的,Car类中并没有这个属性。再就是定义了一个描述电瓶容量的方法。模拟电动汽车时,只要是电动汽车所特有的,可以添加任意数量的属性和方法。

3.3重写父类的方法

        对于父类的方法,只要它不符合子类模拟实物的行为,都可以进行重写。为此,可以在子类中定义一个与要重写与父类名字相同的方法。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的方法。

        假设父类中有个名为fill_gas_tank()的方法,这对电动汽车毫无意义。可做如下修改,这样Python在运行时就会只运行在子类中定义的方法。

def fiil_gas_tank:
    """电动汽车没有油箱"""
    print("This car doesn't need a gas tank")

3.4将实例用作属性

        使用代码模拟实物时,会发现我们给类定义的属性和方法越来越多。在这种情况下,可以将类的一部分提取出来,作为一个独立的类,这样就可以将一个复杂的类拆分成多个协同工作的小类。

class Battery:
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self, battery_size=75):
        """初始化电瓶属性"""
        self.battery_size = battery_size

    def describe_battery(self):
        """打印相关信息"""
        print(f"This car has a {self.battery_size}-kwh battery.")

class ElectricCar(Car):
    """电瓶车的独特之处"""

    def __init__(self, make, model, year):
        """初始化父类属性"""
        super().__init__(make, model, year)
        self.battery = Battery()

    def describe_battery(self):
        """打印一条描述电瓶容量的信息"""
        print(f"This car has a {self.battery}-kwh battery")

my_tesla = ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

         首先,定义了一个名为Battery的新类,它没有继承任何类。并且在_init_()方法中,定义了一个可选的形参battery_size,若未给定形参battery_size的值,则使用默认值75。

        其次,在ElectricCar类中,定义了一个新的属性self.battery,并将实例Battery赋值给它,这样使用句点表示法就可以调用Battery类中的属性和方法。

4.导入类

         随着给类不断添加功能,文件可能变得很长。所以,在Python中允许将类存储在模块中,然后在主程序中导入所需的模块。

4.1导入单个类

        下面将创建一个只包含Car类的模块car.py。

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

    def read_odometer(self):
        """打印一条指出汽车里程的信息"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self, mileage):
        """将里程表读数设置成指定的值,并禁止里程表往回调"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer.")

    def increment_odometer(self, miles):
        """将里程表增加指定的量"""
        self.odometer_reading += miles


         再定义一个my_car.py的文件,用以调用上端模块的程序。先使用import语句将Car类导入,再使用句点表示法来调用其中的属性和方法。

from car import Car

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

4.2在一个模块中存储多个类

        虽然同意模块的类之间应存在某种相关性,但是根据需要可以在一个某块中存储任意数量的类。这样,我们从car.py文件中导入时可以直接导入ElectricCar、Battery类。

class Car:
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = f"{self.year} {self.make} {self.model}"
        return  long_name

    def read_odometer(self):
        """打印一条指出汽车里程的信息"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self, mileage):
        """将里程表读数设置成指定的值,并禁止里程表往回调"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer.")

    def increment_odometer(self, miles):
        """将里程表增加指定的量"""
        self.odometer_reading += miles

class Battery:
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self, battery_size=75):
        """初始化电瓶属性"""
        self.battery_size = battery_size

    def describe_battery(self):
        """打印相关信息"""
        print(f"This car has a {self.battery_size}-kwh battery.")

class ElectricCar(Car):
    """电瓶车的独特之处"""

    def __init__(self, make, model, year):
        """初始化父类属性"""
        super().__init__(make, model, year)
        self.battery = Battery()

    def describe_battery(self):
        """打印一条描述电瓶容量的信息"""
        print(f"This car has a {self.battery}-kwh battery")

4.3从一个模块中导入多个类

        可根据需要在程序文件中导入任意数量的类。在导入多个类时,用逗号来分割各个类。

from car import Car, ElectricCar

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())

my_tesla = ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())

4.4导入整个模块

        还可以导入整个模块,再使用句号表示法来访问需要的类。即使用module_name.ClassName来访问所需要的类。

import car 

my_new_car = car.Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())

my_tesla = car.ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())

4.5导入模块中的所有类

        要导入模块中的所有类,可以使用下面的语法。但是,不推荐使用该语法。

from module_name import *

4.6在一个模块中导入另一个模块

        有时候,需要将类分散到多个模块中,以避免某个模块过大。将类存储到多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类,这时,你需要在前一个模块中导入必要的类。如下,将Car类存储在car.py模块中,将ElectricCar、Battery类,存储在electric_car.py文件中。则代码段如下,注意,因为定义ElectricCar类要用到Car类,所以要用import语句导入Car类。

from car import Car

class Battery:
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self, battery_size=75):
        """初始化电瓶属性"""
        self.battery_size = battery_size

    def describe_battery(self):
        """打印相关信息"""
        print(f"This car has a {self.battery_size}-kwh battery.")

class ElectricCar(Car):
    """电瓶车的独特之处"""

    def __init__(self, make, model, year):
        """初始化父类属性"""
        super().__init__(make, model, year)
        self.battery = Battery()

    def describe_battery(self):
        """打印一条描述电瓶容量的信息"""
        print(f"This car has a {self.battery}-kwh battery")

        调用这两个模块的代码段如下:

from car import Car
from electric_car import ElectricCar

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())

my_tesla = ElectricCar('telsa', 'model s', 2019)
print(my_tesla.get_descriptive_name())

4.7使用别名

        导入类时,也可以使用别名。

from electric_car import ElectricCar as EC

5.Python标准库

        Python标准库是一组模块,我们可以使用import语句来调用它。下面来看看模块random,我们从中导入了两个方法进行示例。

from random import randint
from random import choice

a = randint(1, 6)
print(a)

players = ['charles', 'martina', 'eli']
first_up = choice(players)
print(first_up)

6.类编码风格

        类名应使用驼峰命名法,类名中每个单词的首字母要大写,并且不适用下划线。实例名和模块名中的每个单词必须使用小写字母,并且在每个单词之间加上下划线。

        对于每个类,都应紧跟在类定义之后包含一个文档字符串,用以简要的描述一下该类的功能。

        可以用空行来组织代码,但不要滥用。在类中,可以使用一个空行分隔代码。再模块中,使用两个空行分割代码。

        需要同时导入标准库模块和你自己编写的模块时,先导入标准库模块,再加一个空行后,再导入自己编写的模块。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值