• Python-类


    类将函数和数据整洁地封装起来,让你能够灵活而高效地使用它。
    根据类来创建的对象被称为实例化,这让你能够使用类的实例。

    创建和使用类

    编写一个小狗实例的类,它表示的不是特定的小狗而是任何小狗。
    它具备名字和年龄,可以下蹲和打滚。

    class Dog():
        def __init__(self,name,age):
            self.name=name 
            self.age=age
        def sit(self):
            print(self.name.title()+" is now sitting.")
        def roll_over(self):
            print(self.name.title()+" is rolled over!")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    提示

    1.方法__init__()
    (1). 类中的函数称为方法,你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别就是调用方法。
    (2)init()是一个特殊的方法,每当你根据Dog类创建新的实例时,Python都会自动运行它。(接受变量)
    (3). 在这个方法名称中,开头和结尾各有两个下划线,这是一种约定,旨在避免Python默认方法语普通方法发生名称冲突。
    (4). 我们将方法__init__() 定义成了包含三个形参:self,name,age。在这个方法的定义中,形参self必不可少,还必须位于其它形参前面。因为,Python调用__init__()方法来创建实例时,将自动传入实参到self。每个与类相关联的方法调用都会自动传递实参self,他是一个指向实例本身的引用,让实例能够访问类中的属性和方法。

    Python2.7中创建类

    在Python2.7 中创建类时,需要在括号内加上单词object:

    class ClassName(object):
    	--snip--
    
    • 1
    • 2

    根具类创建实例

    class Dog():
    	--snip--
    my_dog=Dog('willie',6)
    print("my dog's name is "+my_dog.name.title()+'.')
    print("my dog is "+str(my_dog.age)+' years old.')
    
    • 1
    • 2
    • 3
    • 4
    • 5

    访问属性

    句点表示法在Python中很常用,这种语法演示了Python如何获取属性的值。

    my_dog.name
    
    • 1

    调用方法

    要调用方法,可以指定实例名称和要调用的方法,并用句点分隔他们。

    class Dog():
    	--snip--
    my_dog=Dog('willie',6)
    my_dog.sit()
    my_dog.roll_over()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建多个实例

    我们可以同时创建多个实例

    class Dog():
    	--snip--
    my_dog=Dog('willie',6)
    your_dog=Dog('lucy',3)
    print("my dog's name is "+my_dog.name.title()+'.')
    print("my dog is "+str(my_dog.age)+" years old.")
    my_dog.sit()
    print("\nyour dog's name is "+your_dog.name.title()+'.')
    print("your dog is "+str(your_dog.age)+" years old.")
    your_dog.sit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用类和实例

    当类创建完毕后,你的大部分时间都将花在使用根据类创建的实例上。

    car类

    class Car():
        def __init__(self,make,model,year):
            self.make=make
            self.model=model
            self.year=year
        def get_descriptive_name(self):
            long_name = str(self.year)+' '+self.make+' '+self.model
            return long_name.title()
    my_new_car=Car('audi','a4',2016)
    print(my_new_car.get_descriptive_name())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    给属性指定默认值

    给汽车添加一个里程默认值

    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 = str(self.year)+' '+self.make+' '+self.model
            return long_name.title()
        def read_odometer(self):
            print("This car has "+str(self.odometer_reading)+" miles on it.")
    my_new_car=Car('audi','a4',2016)
    print(my_new_car.get_descriptive_name())
    my_new_car.read_odometer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    修改属性的值

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

    直接修改属性的值

    class Car():
    	--snip--
    my_new_car=Car('audi','a4',2016)
    print(my_new_car.get_descriptive_name())
    my_new_car.odometer_reading=23
    my_new_car.read_odometer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过方法修改属性的值

    你可以在类中添加一个方法,用于修改属性的值。

    class Car():
    	--snip--
    	def update_odometer(self,mileage):
            self.odometer_reading=mileage
    my_new_car=Car('audi','a4',2016)
    print(my_new_car.get_descriptive_name())
    my_new_car.odometer_reading=23
    my_new_car.read_odometer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    你可以添加一些逻辑来禁止任何人将里程表往回调。

    class Car():
    	--snip--
    	def update_odometer(self,mileage):
    	if mileage>=self.odometer_reading:
    		self.odometer_reading=mileage
    	else:
    		print("you can't roll back an odometer!")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    有时候需要将属性值递增特定的量,而不是将其设置为全新的值。

    class Car():
    	--snip--
    	def update_odometer(self,mileage):
    		--snip--
    	def increment_odometer(self,miles):
    		self.odometer_reading+=miles
    my_used_car=Car('subaru','outback',2013)
    print(my_used_car.get_descriptive_name())
    my_used_car.update_odometer(23500)
    my_used_car.read_odometer()
    my_used_car.increment_odometer(100)
    my_used_car.read_odometer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    继承

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

    子类的方法__init__()

    创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__()需要父类施以援手。
    提示:父类必须包含在文件中,且位于子类的前面。定义子类时必须在括号内指定父类的名称。
    super()是一个特殊的函数,帮助Python将父类和子类关联起来。父类也称为超类,名称super因此得名。

    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=str(self.year)+' '+self.make+' '+self.model
            return long_name.title()
        def read_odometer(self):
            print("this car has "+str(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('tesla','models',2016)
    print(my_tesla.get_descriptive_name())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Python2.7中的继承

    函数supe() 需要两个实参:子类名和对象self。另外务必在父类括号中指定object。

    class Car(object):
        def __init__(self,make,model,year):
            --snip--
    class EletricCar(Car):
        def __init__(self,make,model,year):
             super(ElectriCar,self).__init__(make,model,year)
            --snip--
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    给予子类定义属性和方法

    让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。

    class Car():
        --snip--
    class ElectricCar(Car):
        def __init__(self,make,model,year):
            super().__init__(make,model,year)
            self.battery_size=70
        def describe_battery(self):
            print("This car has a "+str(self.battery_size)+"-kwh battery.")
    my_tesla=ElectricCar('tesla','model s',2016)
    print(my_tesla.get_descriptive_name())
    my_tesla.describe_battery()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    重写父类的方法

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

    class ElectricCar(Car):
        --snip--
        def fill_gas_tank(self):
            print("This car doesn't need a gas tank!")
    
    • 1
    • 2
    • 3
    • 4

    现在,如果有人对电动汽车调用方法fill_gas_tank(),python将忽略Car类中的方法fill_gas_tank(),转而执行上面的代码。

    将实例用作属性

    使用实例模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。这种情况下,可能需要将类的一部分作为一个独立的类提取出来。你可以将大类拆分成多个协同工作的小类。
    提示:实例是有参数的,注意实例的含义

    class Car():
       --snip--
    class Battery():
        def __init__(self,battery_size=70):
            self.battery_size=battery_size
        def describe_battery(self):
            print("This car has a "+str(self.battery_size)+"-kwh battery.")
    class ElectricCar(Car):
        def __init__(self,make,model,year):
            super().__init__(make,model,year)
            self.battery=Battery()
    my_tesla=ElectricCar('tesla','model s',2016)
    print(my_tesla.get_descriptive_name())
    my_tesla.battery.describe_battery()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    模拟实物

    解决问题时,你从较高的逻辑层面(而不是语法层面);你考虑的不是Python,而是如何使用代码来表示实物。达到这种境界后,你经常会发现,现实世界的建模方法并没有对错之分。有些方法的效率更高,但要找出效率最高的方法,需要经过一定的实践。

    动手试一试

    创建一个Car()的父类,再创建一个子类A_car(),还有一个实例Behavior()用作子类A_car()的属性。
    注意:实例中是有参数的

    
    class Car():
        def __init__(self,make,model,year):
            self.make=make
            self.model=model
            self.year=year
        def all_parameter(self):
            all=self.make+' '+self.model+' '+str(self.year)
            return all
        def year(self):
            print("This car had made "+self.year+'.')
    
    class Behavior():
        def __init__(self,state='running'):
            self.state=state 
        def states(self):
            print("this car is "+self.state+'.')
    
    
    class A_car(Car):
        def __init__(self,make,model,year):
            super().__init__(make,model,year)
            self.s=Behavior()
    new_car=A_car('zhongguo','a6',2016)
    print(new_car.all_parameter())
    new_car.s.states()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    导入类

    随着你不断个类添加功能,文件可能变得很长,即使你妥善地使用了继承亦如此。故,为遵顼python的总体理念,应让文件尽可能整洁;python允许你将类存储在模块中,然后在主程序中导入所需的模块。

    导入单个类

    创建两个.py的模块,一个为car.py写入了Car()类的代码,再写一个my_car.py的模块,用这个模块来导入car.py中的类,并创建实例。

    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=str(self.year)+' '+self.make+' '+self.model
            return long_name.title()
        def read_odometer(self):
            print("this car has "+str(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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    my_car.py
    
    from test import Car
    my_new_car=Car('audi','a4',2016)
    print(my_new_car.get_descriptive_name())
    my_new_car.odometer_reading=27
    my_new_car.read_odometer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在一个模块中存储多个类

    虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。
    将Battery和ElectricCar都加入模块car.py中。

    car.py
    
    class Car():
    	--snip--
    class Battery():
        def __init__(self, battery_size=70):
            self.battery_size = battery_size
    
        def describe_battery(self):
            print("This car has a " + str(self.battery_size) + "-kwh battery.")
    
        def get_range(self):
            if self.battery_size == 70:
                rage = 240
            elif self.battery_size == 85:
                rage = 270
            message = "This car can go approximately " + str(rage)
            message += " miles on a full charge."
            print(message)
    
    
    class ElectricCar(Car):
        def __init__(self, make, model, year):
            super().__init__(make, model, year)
            self.battery = Battery()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在my_car.py中输入:

    from test import ElectricCar
    my_tesla=ElectricCar('tesla','model s',2016)
    print(my_tesla.get_descriptive_name())
    my_tesla.battery.describe_battery()
    my_tesla.battery.get_range()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    困惑:如何将参数传入实例class Battery(),似乎self.battery_size == 85永远无法实现。

    从一个模块中导入多个类

    从一个模块中导入多个类时,用逗号分隔了各个类。

    from car import Car,ElectricCar
    my_beetle=Car('volkswagen','beetle',2016)
    print(my_beetle.get_descriptive_name())
    my_tesla=ElectricCar('tesla','roadster',2016)
    print(my_tesla.get_descriptive_name())
    
    • 1
    • 2
    • 3
    • 4
    • 5

    导入整个类

    你还可以导入整个模块,再使用点句法表示访问需要的类。
    可避免类中的模块名和当前文件使用名称冲突的问题。

    import car
    my_beetle=car.Car('volkswagen','beetle',2016)
    print(my_beetle.get_descriptive_name())
    my_tesla=car.ElectricCar('tesla','roadster',2016)
    print(my_tesla.get_descriptive_name())
    
    • 1
    • 2
    • 3
    • 4
    • 5

    导入模块中的所有类

    注意:可能会产生会发生重名的错误。

    frommodule_name import *
    
    • 1

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

    有时候,需要将类分散到多个模块,以免模块太大,或在同一个模块中存储不相关的类。将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。这种情况下,可在前一个模块中导入必要的类。
    将Car类存储在一个模块中,并将EletricCar和Battery类存储在另一个模块中。

    electric_car.py
    
    from car import Car
    class Battery():
    	--snip--
    class ElectricCar(Car):
    	--snip--
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    car.py
    
    class Car():
    	--snip--
    
    • 1
    • 2
    • 3
    • 4

    分别从每个模块中导入类

    from car import Car()
    from electric_car import ElectricCar
    my_beetle=Car('volkswagen','beetle',2016)
    print(my_beetle.get_descriptive_name())
    my_tesla=ElectricCar('tesla','roadster',2016)
    print(my_tesla.get_descriptive_name())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    自定义工作流程

    一开始让代码结构尽可能简单。先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移到独立的模块中。如果你喜欢模块和文件的交互方式,可在项目开始时就尝试将类存储到模块中。先找出让你能够编写出可行的代码方式,再尝试让代码更为组织有序。

    Python标准库

    Python标准库是一组模块,安装的Python都包含它。你可以使用其他程序员编写好的模块,只需要在程序开头包含一条简单的import语句。
    试一试:使用collections模块中的OrderedDict类来记录字典添加键值对的添加顺序。

    from collections import OrdereDict
    favorite_languages=OrderedDict()
    favorite_languages['jen']='python'
    favorite_languages['sarah']='c'
    favorite_languages['edward']='ruby'
    favorite_languages['phil']='python'
    for name,language in favorite_languages.items():
    	print(name.title()+"'s favorite language is "+language.title()+'.')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    类编码风格

    1. 类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不适用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
    2. 对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也应该包含一个文档字符串,对其中的类可用于做什么进行描述。
    3. 可用空行来组织代码,但不要滥用。类中,可用一个空行来分隔;而在模块中可使用两个空格来分隔。
    4. 需要同时导入标准库和你自己编写的模块时,先编写导入标准模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句。
  • 相关阅读:
    c#弹性和瞬态故障处理库Polly
    16、window11+visual studio 2022+cuda+ffmpeg进行拉流和解码(RTX3050)
    知识点8--SSM项目整合redis、kafka、es以及整合es高亮
    SSD【目标检测篇】
    Vue生命周期
    Camtasia Studio2024最新版本正式更新上线!
    awk语法-02-运算、数组、格式化输出
    Vue3 + vant + Tab组件动态传递实现选项卡切换
    【JavaEE初阶】 synchronized关键字详解
    【数据结构】链表超全整理~
  • 原文地址:https://blog.csdn.net/m0_61786761/article/details/126752102