• 主页
  • 课程

    关于课程

    • 课程归档
    • 成为一名讲师
    • 讲师信息
    教学以及管理操作教程

    教学以及管理操作教程

    ¥1,000.00 ¥100.00
    阅读更多
  • 特色
    • 展示
    • 关于我们
    • 问答
  • 事件
  • 个性化
  • 博客
  • 联系
  • 站点资源
    有任何问题吗?
    (00) 123 456 789
    weinfoadmin@weinformatics.cn
    注册登录
    恒诺新知
    • 主页
    • 课程

      关于课程

      • 课程归档
      • 成为一名讲师
      • 讲师信息
      教学以及管理操作教程

      教学以及管理操作教程

      ¥1,000.00 ¥100.00
      阅读更多
    • 特色
      • 展示
      • 关于我们
      • 问答
    • 事件
    • 个性化
    • 博客
    • 联系
    • 站点资源

      老俊俊的生信笔记

      • 首页
      • 博客
      • 老俊俊的生信笔记
      • python 学习之类

      python 学习之类

      • 发布者 weinfoadmin
      • 分类 老俊俊的生信笔记
      • 日期 2021年12月21日
      测试开头


      点击上方关注“公众号”

      python 学习之类

      1引言

      面向对象编程 是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。编写类时,你定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情景,其逼真程度达到了令人惊讶的地步。

      根据类来创建对象称为实例化 ,这让你能够使用类的实例。在本章中,你将编写一些类并创建其实例。你将指定可在实例中存储什么信息,定义可对这些实例执行哪些操作。你还将编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码。你将把自己编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类。

      2创建和使用类

      使用类几乎可以模拟任何东西。下面来编写一个表示小狗的简单类 Dog ,它表示的不是特定的小狗,而是任何小狗。对于大多数宠物狗,我们都知道些什么呢?它们都有名字和年龄。我们还知道,大多数小狗还会蹲下和打滚。由于大多数小狗都具备上述两项信息(名字和年龄)和两种行为(蹲下和打滚),我们的 Dog 类将包含它们。这个类让 Python 知道如何创建表示小狗的对象。编写这个类后,我们将使用它来创建表示特定小狗的实例。

      创建 Dog 类

      根据 Dog 类创建的每个实例都将存储名字和年龄,我们赋予了每条小狗蹲下( sit() )和打滚( roll_over() )的能力:

      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!")

      根据约定,在 Python 中,首字母大写的名称指的是类。这个类定义中 没有圆括号,因为要从空白创建这个类。编写了一个文档字符串,对这个类的功能做了描述。

      方法init():

      类中的函数称为 方法 。你在前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。__init__() 是一个特殊方法,每当你根据 Dog 类创建新实例时,Python 都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免 Python 默认方法与普通方法发生名称冲突。务必确保 init() 的两边都有两个下划线,否则当你使用类来创建实例时,将不会自动调用这个方法,进而引发难以发现的错误。

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

      定义的两个变量都有 前缀 self 。以 self 为前缀的变量可供类中的所有方法使用,可以通过类的任何实例来访问。self.name = name 获取与形参 name 相关联的值,并将其赋给变量 name ,然后该变量被关联到当前创建的实例。self.age = age 的作用与此类似。像这样可通过实例访问的变量称为属性 。

      Dog 类还定义了另外两个方法:sit() 和 roll_over()。这些方法执行时不需要额外的信息,因此它们只有一个形参 self 。我们随后将创建的实例能够访问这些方法,换句话说,它们都会蹲下和打滚。当前,sit() 和 roll_over() 所做的有限,只是打印一条消息,指出小狗正在蹲下或打滚。

      根据类创建实例

      可将类视为有关如何创建实例的说明。Dog 类是一系列说明,让 Python 知道如何创建表示特定小狗的实例。

      下面来创建一个表示特定小狗的实例:

      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's name is Willie.
      My dog is 6 years old.

      让 Python 创建一条名字为’Willie’ 、年龄为 6 的小狗。遇到这行代码时,Python 使用实参’Willie’ 和 6 调用 Dog 类的方法init() 。方法init() 创建一个表示特定小狗的实例,并使用提供的值来设置属性 name 和 age 。接下来,Python 返回一个表示这条小狗的实例,而我们将这个实例赋给了变量 my_dog 。在这里,命名约定很有用:通常可认为首字母大写的名称(如 Dog )指的是类,而小写的名称(如 my_dog )指的是根据类创建的实例。

      访问属性:

      要访问实例的属性,可使用 句点表示法。编写了如下代码来访问 my_dog 的属性 name 的值:

      my_dog.name

      调用方法:

      根据 Dog 类创建实例后,就能使用句点表示法来调用 Dog 类中定义的任何方法了。下面来让小狗蹲下和打滚:

      my_dog = Dog('Willie', 6)
      my_dog.sit()
      my_dog.roll_over()

      Willie is now sitting.
      Willie rolled over!

      创建多个实例:

      可按需求根据类创建任意数量的实例。下面再创建一个名为 your_dog 的小狗实例:

      my_dog = Dog('Willie', 6)
      your_dog = Dog('Lucy', 3)

      print(f"My dog's name is {my_dog.name}.")
      print(f"My dog is {my_dog.age} years old.")
      my_dog.sit()

      print(f"nYour dog's name is {your_dog.name}.")
      print(f"Your dog is {your_dog.age} years old.")
      your_dog.sit()

      My dog's name is Willie.
      My dog is 6 years old.
      Willie is now sitting.

      Your dog'
      s name is Lucy.
      Your dog is 3 years old.
      Lucy is now sitting.

      在本例中创建了两条小狗,分别名为 Willie 和 Lucy。每条小狗都是一个独立的实例,有自己的一组属性,能够执行相同的操作。

      3使用类和实例

      类编写好后,你的大部分时间将花在根据类创建的实例上。你需要执行的一个重要任务是修改实例的属性。可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。

      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 = f"{self.year} {self.make} {self.model}"
              return long_name.title()

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

      2019 Audi A4

      与前面的 Dog 类中一样,这个方法的第一个形参为 self 。该方法还包含另外三个形参:make 、model 和 year 。方法init() 接受这些形参的值,并将它们赋给根据这个类创建的实例的属性。创建新的 Car 实例时,需要指定其制造商、型号和生产年份。

      定义了一个名为 get_descriptive_name() 的方法。它使用属性 year 、make 和 model 创建一个对汽车进行描述的字符串,让我们无须分别打印每个属性的值。为在这个方法中访问属性的值,使用了 self.make 、self.model 和 self.year 。

      给属性指定默认值

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

      下面来添加一个名为 odometer_reading 的属性,其初始值总是为 0。我们还添加了一个名为 read_odometer() 的方法,用于读取汽车的里程表:

      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.title()
          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()

      2019 Audi A4
      This car has 0 miles on it.

      Python 将创建一个名为 odometer_reading 的属性,并将其初始值设置为 0。

      修改属性的值

      我们能以三种方式修改属性的值:直接通过实例进行修改,通过方法进行设置,以及通过方法进行递增(增加特定的值)。下面依次介绍这些方式。

      直接修改属性的值:

      要修改属性的值,最简单的方式是通过实例直接访问它。下面的代码直接将里程表读数设置为 23:

      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()

      2019 Audi A4
      This car has 23 miles on it.

      通过方法修改属性的值:

      如果有方法能替你更新属性,将大有裨益。这样就无须直接访问属性,而可将值传递给方法,由它在内部进行更新。

      下面的示例演示了一个名为 update_odometer() 的方法:

      class Car:
          --snip--

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

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

      my_new_car.update_odometer(23)
      my_new_car.read_odometer()

      2019 Audi A4
      This car has 23 miles on it.

      对 Car 类所做的唯一修改是在添加了方法 update_odometer() 。这个方法接受一个里程值,并将其赋给 self.odometer_reading 。调用 update_odometer() ,并向它提供了实参 23。

      可对方法 update_odometer() 进行扩展,使其在修改里程表读数时做些额外的工作。下面来添加一些逻辑,禁止任何人将里程表读数往回调:

      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!")

      现在,update_odometer() 在修改属性前检查指定的读数是否合理。如果新指定的里程(mileage )大于或等于原来的里程(self.odometer_reading ),就将里程表读数改为新指定的里程;否则发出警告,指出不能将里程表往回调。

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

      有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手车,且从购买到登记期间增加了 100 英里的里程。下面的方法让我们能够传递这个增量,并相应地增大里程表读数:

      class Car:
          --snip--

          def update_odometer(self, mileage):
              --snip--

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

      my_used_car = Car('subaru', 'outback', 2015)
      print(my_used_car.get_descriptive_name())

      my_used_car.update_odometer(23_500)
      my_used_car.read_odometer()

      my_used_car.increment_odometer(100)
      my_used_car.read_odometer()

      2015 Subaru Outback
      This car has 23500 miles on it.
      This car has 23600 miles on it.

      新增的方法 increment_odometer() 接受一个单位为英里的数,并将其加入 self.odometer_reading 中。创建一辆二手车 my_used_car 。调用方法 update_odometer() 并传入 23_500 ,将这辆二手车的里程表读数设置为 23 500。调用 increment_odometer() 并传入 100 ,以增加从购买到登记期间行驶的 100 英里。

      你可以轻松地修改这个方法,以禁止增量为负值,从而防止有人利用它来回调里程表。

      4继承

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

      子类的方法init()

      在既有类的基础上编写新类时,通常要调用父类的方法init**() 。这将初始化在父类init() 方法中定义的所有属性,从而让子类包含这些属性**。

      例如,下面来模拟电动汽车。电动汽车是一种特殊的汽车,因此可在前面创建的 Car 类的基础上创建新类 ElectricCar 。这样就只需为电动汽车特有的属性和行为编写代码。

      下面来创建 ElectricCar 类的一个简单版本,它具备 Car 类的所有功能:

      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.title()

          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('tesla', 'model s', 2019)
      print(my_tesla.get_descriptive_name())

      2019 Tesla Model S

      首先是 Car 类的代码。创建子类时,父类必须包含在当前文件中,且位于子类前面。定义了子类 ElectricCar 。定义子类时,必须在圆括号内指定父类的名称。方法init() 接受创建 Car 实例所需的信息。

      super() 是一个特殊函数,让你能够调用父类的方法。这行代码让 Python 调用 Car 类的方法init() ,让 ElectricCar 实例包含这个方法中定义的所有属性。父类也称为超类 (superclass),名称 super 由此而来。

      除方法init_() 外,电动汽车没有其他特有的属性和方法。当前,我们只想确认电动汽车具备普通汽车的行为。

      给子类定义属性和方法

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

      下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。我们将存储电瓶容量,并编写一个打印电瓶描述的方法:

      class Car:
          --snip--

      class ElectricCar(Car):
          """电动汽车的独特之处。"""

          def __init__(self, make, model, year):
              """
              初始化父类的属性。
              再初始化电动汽车特有的属性。
              "
      ""
              super().__init__(make, model, year)
              self.battery_size = 75

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

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

      2019 Tesla Model S
      This car has a 75-kWh battery.

      添加了新属性 self.battery_size ,并设置其初始值( 75 )。根据 ElectricCar 类创建的所有实例都将包含该属性,但所有 Car 实例都不包含它。还添加了一个名为 describe_battery() 的方法,打印有关电瓶的信息。调用这个方法时,将看到一条电动汽车特有的描述。

      对于 ElectricCar 类的特殊程度没有任何限制。模拟电动汽车时,可根据所需的准确程度 添加任意数量的属性和方法。如果一个属性或方法是任何汽车都有的,而不是电动汽车特有的,就应将其加入到 Car 类而非 ElectricCar 类中。这样,使用 Car 类的人将获得相应的功能,而 ElectricCar 类只包含处理电动汽车特有属性和行为的代码。

      重写父类的方法

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

      假设 Car 类有一个名为 fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式:

      class ElectricCar(Car):
          --snip--

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

      现在,如果有人对电动汽车调用方法 fill_gas_tank() ,Python 将忽略 Car 类中的方法 fill_gas_tank() ,转而运行上述代码。使用继承时,可让子类保留从父类那里继承而来的精华,并剔除不需要的糟粕。

      将实例用作属性

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

      例如,不断给 ElectricCar 类添加细节时,我们可能发现其中包含很多专门针对汽车电瓶的属性和方法。在这种情况下,可将这些属性和方法提取出来,放到一个名为 Battery 的类中,并将一个 Battery 实例作为 ElectricCar 类的属性:

      class Car:
          --snip--

      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()

      my_tesla = ElectricCar('tesla', 'model s', 2019)

      print(my_tesla.get_descriptive_name())
      my_tesla.battery.describe_battery()

      2019 Tesla Model S
      This car has a 75-kWh battery.

      定义一个名为 Battery 的新类,它没有继承任何类。方法init() 除 self 外,还有另一个形参 battery_size 。这个形参是可选的:如果没有给它提供值,电瓶容量将被设置为 75。方法 describe_battery() 也移到了这个类中。

      在 ElectricCar 类中,添加了一个名为 self.battery 的属性。这行代码让 Python 创建一个新的 Battery 实例(因为没有指定容量,所以为默认值 75),并将该实例赋给属性 self.battery 。每当方法init() 被调用时,都将执行该操作,因此现在每个 ElectricCar 实例都包含一个自动创建的 Battery 实例。

      5导入类

      随着不断给类添加功能,文件可能变得很长,即便妥善地使用了继承亦如此。为遵循 Python 的总体理念,应让文件尽可能整洁。Python 在这方面提供了帮助,允许将类存储在模块中,然后在主程序中导入所需的模块。

      导入单个类

      下面来创建一个只包含 Car 类的模块,下面是模块 car.py ,其中只包含 Car 类的代码:

      """一个可用于表示汽车的类。"""

      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.title()

          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,在其中导入 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()

      2019 Audi A4
      This car has 23 miles on it.

      import 语句让 Python 打开模块 car 并导入其中的 Car 类。这样,我们就可以使用 Car 类,就像它是在这个文件中定义的一样。输出与我们在前面看到的一样。

      导入类是一种有效的编程方式。如果这个程序包含整个 Class 类,它该有多长啊!通过将这个类移到一个模块中并导入该模块,依然可以使用其所有功能,但主程序文件变得整洁而易于阅读了。这还让你能够将大部分逻辑存储在独立的文件中。确定类像你希望的那样工作后,就可以不管这些文件,而专注于主程序的高级逻辑了。

      在一个模块中存储多个类

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

      """一组用于表示燃油汽车和电动汽车的类。"""

      class Car:
          --snip--

      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.")

          def get_range(self):
              """打印一条描述电瓶续航里程的消息。"""
              if self.battery_size == 75:
                  range = 260
              elif self.battery_size == 100:
                  range = 315

              print(f"This car can go about {range} miles on a full charge.")

      class ElectricCar(Car):
          """模拟电动汽车的独特之处。"""

          def __init__(self, make, model, year):
              """
              初始化父类的属性。
              再初始化电动汽车特有的属性。
              "
      ""
              super().__init__(make, model, year)
              self.battery = Battery()

      现在,可以新建一个名为 my_electric_car.py 的文件,导入 ElectricCar 类,并创建一辆电动汽车了:

      from car import ElectricCar
      my_tesla = ElectricCar('tesla', 'model s', 2019)

      print(my_tesla.get_descriptive_name())
      my_tesla.battery.describe_battery()
      my_tesla.battery.get_range()

      2019 Tesla Model S
      This car has a 75-kWh battery.
      This car can go about 260 miles on a full charge.

      从一个模块中导入多个类

      可根据需要在程序文件中导入任意数量的类。如果要在同一个程序中创建普通汽车和电动汽车,就需要将 Car 类和 ElectricCar 类都导入:

      from car import Car, ElectricCar

      my_beetle = Car('volkswagen', 'beetle', 2019)
      print(my_beetle.get_descriptive_name())

      my_tesla = ElectricCar('tesla', 'roadster', 2019)
      print(my_tesla.get_descriptive_name())

      2019 Volkswagen Beetle
      2019 Tesla Roadster

      从一个模块中导入多个类时,用逗号分隔了各个类。导入必要的类后,就可根据需要创建每个类的任意数量实例。

      导入整个模块

      还可以导入整个模块,再使用句点表示法访问需要的类。这种导入方式很简单,代码也易于阅读。因为创建类实例的代码都包含模块名,所以不会与当前文件使用的任何名称发生冲突。

      下面的代码导入整个 car 模块,并创建一辆普通汽车和一辆电动汽车:

      import car

      my_beetle = car.Car('volkswagen', 'beetle', 2019)
      print(my_beetle.get_descriptive_name())

      my_tesla = car.ElectricCar('tesla', 'roadster', 2019)
      print(my_tesla.get_descriptive_name())

      导入了整个 car 模块。接下来,使用语法 module_name.ClassName 访问需要的类。

      导入模块中的所有类

      要导入模块中的每个类,可使用下面的语法:

      from module_name import *

      不推荐使用这种导入方式,原因有二:

      1. 第一,如果只看文件开头的 import 语句,就能清楚地知道程序使用了哪些类,将大有裨益。然而这种导入方式没有明确地指出使用了模块中的哪些类。
      2. 第二,这种方式还可能引发名称方面的迷惑。如果不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。

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

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

      下面将 Car 类存储在一个模块中,并将 ElectricCar 类和 Battery 类存储在另一个模块中。将第二个模块命名为 electric_car.py(这将覆盖前面创建的文件 electric_car.py),并将 Battery 类和 ElectricCar 类复制到这个模块中:

      """一组可用于表示电动汽车的类。"""

      from car import Car

      class Battery:
          --snip--

      class ElectricCar(Car):
          --snip--

      ElectricCar 类需要访问其父类 Car ,因此直接将 Car 类导入该模块中。

      现在可以分别从每个模块中导入类,以根据需要创建任何类型的汽车了:

      from car import Car
      from electric_car import ElectricCar

      my_beetle = Car('volkswagen', 'beetle', 2019)
      print(my_beetle.get_descriptive_name())

      my_tesla = ElectricCar('tesla', 'roadster', 2019)
      print(my_tesla.get_descriptive_name())

      2019 Volkswagen Beetle
      2019 Tesla Roadster

      使用别名

      第 8 章说过,使用模块来组织项目代码时,别名大有裨益。导入类时,也可为其指定别名。

      例如,要在程序中创建大量电动汽车实例,需要反复输入 ElectricCar ,非常烦琐。为避免这种烦恼,可在 import 语句中给 ElectricCar 指定一个别名:

      from electric_car import ElectricCar as EC

      6Python 标准库

      Python 标准库 是一组模块,我们安装的 Python 都包含它。你现在对函数和类的工作原理已有大致的了解,可以开始使用其他程序员编写好的模块了。可以使用标准库中的任何函数和类,只需在程序开头包含一条简单的 import 语句即可。下面来看看模块 random ,它在你模拟很多现实情况时很有用。

      在这个模块中,一个有趣的函数是** randint()** 。它将两个整数作为参数,并随机返回一个位于这两个整数之间(含)的整数。下面演示了如何生成一个位于 1 和 6 之间的随机整数:

      from random import randint
      randint(1, 6)

      4

      在模块 random 中,另一个有用的函数是 choice() 。它将一个列表或元组作为参数,并随机返回其中的一个元素:

      from random import choice
      players = ['charles', 'martina', 'michael', 'florence', 'eli']
      first_up = choice(players)
      first_up

      'martina'

      7类编码风格

      你必须熟悉有些与类相关的编码风格问题,在编写的程序较复杂时尤其如此。

      类名应采用 驼峰命名法 ,即将 类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。

      对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。

      可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。

      需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的 import 语句,再添加一个空行,然后编写导入你自己编写的模块的 import 语句。在包含多条 import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何处。

      8小结

      在本章中,你学习了:如何编写类;如何使用属性在类中存储信息,以及如何编写方法,以让类具备所需的行为;如何编写方法init**()** ,以便根据类创建包含所需属性的实例。你见识了如何修改实例的属性,包括直接修改以及通过方法进行修改。你还了解了使用继承可简化相关类的创建工作,以及将一个类的实例用作另一个类的属性可让类更简洁。

      你了解到,通过将类存储在模块中,并在需要使用这些类的文件中导入它们,可让项目组织有序。你学习了 Python 标准库,并见识了一个使用模块 random 的示例。最后,你学习了编写类时应遵循的 Python 约定。


      python 学习之类


      欢迎加入生信交流群。加我微信我也拉你进 微信群聊 老俊俊生信交流群 哦,数据代码已上传至QQ群,欢迎加入下载。

      群二维码:

      python 学习之类

      老俊俊微信:


      python 学习之类

      知识星球:


      python 学习之类


      所以今天你学习了吗?

      欢迎小伙伴留言评论!

      点击我留言!

      今天的分享就到这里了,敬请期待下一篇!

      最后欢迎大家分享转发,您的点赞是对我的鼓励和肯定!

      如果觉得对您帮助很大,赏杯快乐水喝喝吧!



       往期回顾 




      ◀用 python 画个火山图

      ◀python 学习之函数

      ◀geneExpressionFromGEO 下载并注释芯片数据

      ◀python 学习之用户输入和 while 循环

      ◀python 学习之字典

      ◀组会文献分享 — YTHDF2 介导靶基因 mRNA 降解参与前列腺癌进展

      ◀python 学习之 if 语句

      ◀python 学习之列表

      ◀单细胞优质公众号及视频教程!

      ◀python 变量和简单数据类型

      ◀…

      测试结尾

      请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!

      • 分享:
      作者头像
      weinfoadmin

      上一篇文章

      用 python 画个火山图
      2021年12月21日

      下一篇文章

      文件和异常
      2021年12月22日

      你可能也喜欢

      8-1651542331
      跟着Nature学绘图(2) 箱线图-累积分布曲线图
      2 5月, 2022
      9-1651542322
      Julia 笔记之字符串
      2 5月, 2022
      0-1651542343
      Julia 笔记之数学运算和初等函数
      1 5月, 2022

      搜索

      分类

      • R语言
      • TCGA数据挖掘
      • 单细胞RNA-seq测序
      • 在线会议直播预告与回放
      • 数据分析那些事儿分类
      • 未分类
      • 生信星球
      • 老俊俊的生信笔记

      投稿培训

      免费

      alphafold2培训

      免费

      群晖配置培训

      免费

      最新博文

      Nature | 单细胞技术揭示衰老细胞与肌肉再生
      301月2023
      lncRNA和miRNA生信分析系列讲座免费视频课和课件资源包,干货满满
      301月2023
      如何快速批量修改 Git 提交记录中的用户信息
      261月2023
      logo-eduma-the-best-lms-wordpress-theme

      (00) 123 456 789

      weinfoadmin@weinformatics.cn

      恒诺新知

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      链接

      • 课程
      • 事件
      • 展示
      • 问答

      支持

      • 文档
      • 论坛
      • 语言包
      • 发行状态

      推荐

      • iHub汉语代码托管
      • iLAB耗材管理
      • WooCommerce
      • 丁香园论坛

      weinformatics 即 恒诺新知。ICP备案号:粤ICP备19129767号

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      要成为一名讲师吗?

      加入数以千计的演讲者获得100%课时费!

      现在开始

      用你的站点账户登录

      忘记密码?

      还不是会员? 现在注册

      注册新帐户

      已经拥有注册账户? 现在登录

      close
      会员购买 你还没有登录,请先登录
      • ¥99 VIP-1个月
      • ¥199 VIP-半年
      • ¥299 VIP-1年
      在线支付 激活码

      立即支付
      支付宝
      微信支付
      请使用 支付宝 或 微信 扫码支付
      登录
      注册|忘记密码?