Python基础编程——类(二)

Stella981
• 阅读 469

Python基础编程——类(二)

Python基础编程——类(二)

继承

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

子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

子类的方法__init_()

创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。

Python基础编程——类(二)

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

super()是一个特殊函数,将父类和子类关联起来。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的所有属性。

为测试继承是否能够正确的发挥作用,我们创建ElectricCar类的一个实例,并将其存储在变量my_tesla中。这行代码调用ElectricCar类中定义的方法__init__(),后者让Python调用父类Car中定义的方法__init__()。

Python基础编程——类(二)

给子类定义属性和方法

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

Python基础编程——类(二)

首先,我们添加了新属性self.battery_size,并设置其初始值70.根据ElectricCar类创建的所有实例都将包含这个属性,但所有Car实例都不包含它。还添加了一名为describe_battery()的方法。对于ElectricCar类的特殊化程度没有任何限制。

Python基础编程——类(二)

重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法相同。

Python基础编程——类(二)

将实例用作属性

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

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 Battery():
   def __init__(self,battery_size=70):
       self.battery_size = battery_size
       
   def decribe_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.decribe_battery()

首先,我们定义一个名为Battery的新类,它没有继承任何类。方法__init__()除self外,还有另一个形参battery_size。这个形参是可选的:如果没有给它提供值,将设置为70.方法describe_battery()也移到了这个类中。

在ElectricCar类中,添加了一个名为self.battery的属性。并将该实际存储在属性self.battery中。每当方法__init__()被调用时,都将执行该操作。

Python基础编程——类(二)

导入单个类

随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承。为遵循python的总体理念,应让文件尽可能整洁。下面来创建一个值包含Car类的模块。这让我们面临一个微妙的命名问题:在上篇文章中,已经有一个名为car.py的文件,因为它包含表示汽车的代码。我们将这样解决这个命名问题:将Car类存储在一个名为car.py的模块中,该模块将覆盖前面使用的文件car.py。

Python基础编程——类(二)

上图,我们包含了一个模块级文档字符串,对该模块的内容做了简要的描述。下面来创建另一个文件——my_car.py,在其中导入Car类并创建其实例。

Python基础编程——类(二)

import语句让Python打开模块car,并导入其中的Car类。

Python基础编程——类(二)

在一个模块中存储多个类

虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。

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 Battery():
   def __init__(self,battery_size=70):
       self.battery_size = battery_size

   def decribe_battery(self):
       print("This car has a " + str(self.battery_size) + "-kWh battery.")

   def get_range(self):
       if self.battery_size == 70:
           range = 240
       elif self.battery_size == 85:
           range = 270

       message = "This car can go approximately " + str(range)
       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()

新建一个名为my_electric_car.py的文件,导入ElectricCar类;

from car import ElectricCar

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

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

输出与前面看到的相同,但大部分逻辑都隐藏在一个模块中;

Python基础编程——类(二)

从一个模块中导入多个类

可根据需要在程序文件中导入任意数量的类。

Python基础编程——类(二)

从一个模块中导入多个类时,用逗号分隔了各个类。以上红点3和红点6代码行分别创建了普通汽车和电动汽车;

Python基础编程——类(二)

导入整个模块

导入整个模块,在使用句点表示访问需要的类。由于创建类实例的代码都包含模块名,因此不会与当前文件使用的任何名称发生冲突;

Python基础编程——类(二)

Python基础编程——类(二)

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

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

将Car类存储在一个模块中,并将ElectricCar和Battery类存储在另一个模块中。将第二个模块名名为electric_car.py,并将Battery和ElectricCar类复制到这个模块中

Python基础编程——类(二)

将Car类导入该模块中。如果我们忘记第一行代码,Python将在我们试图创建ElectricCar实例时引发错误。我们还需更新模块car,使其包含Car类;

Python基础编程——类(二)

现在可以分别从每个模块中导入类;

Python基础编程——类(二)

从模块car中导入了Car类,并从模块中electric_car中导入ElectricCar类。

Python基础编程——类(二)

类编码风格

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

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

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

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

往期 精彩回顾

Python变量和简单数据类型(一)

Python变量和简单数据类型(二)

Python编程入门到实践—列表篇(一)

Python编程入门到实践—列表篇(二)

Python基础编程—操作列表篇(一)

Python基础编程—操作列表篇(二)

Python基础编程——if语句篇(一)

Python基础编程——if语句篇(二)

Python基础编程—字典篇(一)

Python基础编程—字典篇(二)

Python基础编程——函数(一)

Python基础编程——函数(二)

Python基础编程——类(一)

TCP/IP协议及三次握手、四次断开详解

Linux下MySQL基本操作

Hadoop基础理论知识

Python基础编程——类(二)

Python基础编程——类(二)

Python基础编程——类(二)

Python基础编程——类(二)

本文分享自微信公众号 - 杰哥的IT之旅(Jake_Internet)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这