python 基础篇 类基础与继承
先来简单解释几个概念
- 类:一群有着相同属性和函数的对象的集合,这里对应 Python 的 class。
- 对象:集合中的一个事物,这里对应由 class 生成的某一个 object,比如代码中的 harry_potter_book。
- 属性:对象的某个静态特征,比如上述代码中的 title、author 和
__context
。- 私有属性:是指不希望在类的函数之外的地方被访问和修改的属,以
__
(注意,此处有两个_
) 开头,就默认这个属性是私有属性。
- 私有属性:是指不希望在类的函数之外的地方被访问和修改的属,以
- 函数或方法:对象的某个动态能力,比如代码中的 intercept_context () 函数
属性和方法分类
属性
- 类属性 (属于类,每个类一份)
- 实例属性 (属于对象,每个对象一份)
方法(按作用)
- 构造方法
__init__
- 析构函数
__del__
- 显示函数
__str__
方法(按类型)
- 类方法
- 实例方法
- 静态方法
简单示例
这里不区分公有属性和私有属性,公有属性和私有属性相对于类内和类外来说的。
class Document():
# 类属性,又称静态属性
# 类和对象都可以方便访问这些常量而不用重新构造
# 类中使用 self.WELCOME_STR ,或者在类外使用 Entity.WELCOME_STR
WELCOME_STR = 'Welcome! The context for this book is {}.'
# 构造函数
# 把要先初始化的属性放到这个函数里
def __init__(self, title, author, context):
print('init function called')
# 实例属性
# 调用:被对象调用
#
self.title = title
self.author = author
self.__context = context
# 类方法
# 定义:用 @classmethod 装饰且第一个参数一般为 cls
# 调用:可以被类或者对象调用
# 变量范围:类方法只能访问类属性(静态属性),不能访问实例属性(动态属性)
# 场景:使用在与类进行交互,但不和其 实例 进行交互的函数方法上
# 例子:类函数最常用的功能是实现不同的 init 构造函数,比如上文代码中,我们使用 create_empty_book 类函数,来创造新的书籍对象
@classmethod
def create_empty_book(cls, title, author):
return cls(title=title, author=author, context='nothing')
# 实例方法,又叫普通方法
# 定义:第一个参数 self 代表当前对象的引用,可以通过此函数
# 调用:只能被对象调用
# 场景:来实现想要的查询/修改类的属性等功能
#
def get_context_length(self):
# return len(self.__context)
return len(self.WELCOME_STR)
# 静态方法
# 定义:用 @staticmethod 装饰的不带 self 参数的方法
# 调用:可以被类或者对象调用
# 场景:修饰的方法是放在类外的函数,我们为了方便将他移动到了类里面,它对类的运行无影响
# 当使用了静态方法后,该函数下无法在调用类的变量和实例的变量。
# 静态方法名义上归类管理,实际中在静态方法中无法访问类和实例中的任何属性。
@staticmethod
def get_welcome(context):
return Document.WELCOME_STR.format(context)
# 显示函数
# str函数或者print函数--->obj.__str__()
# repr或者交互式解释器--->obj.__repr__()
# str函数或者print函数如果__str__没有被定义,那么就会使用__repr__来代替输出
# str函数或者print函数如果__str__被定义,那么__repr__就不会执行
# 注意:这俩方法的返回值必须是字符串,否则抛出异常
def __str__(self):
return "test class"
# 析构函数
# 可以用来释放内存空间
# 比如关闭数据库的连接
def __del__(self):
pass
empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 'Professor Sheridan Simove')
print(Document.WELCOME_STR)
print(empty_book.get_context_length())
print(empty_book.get_welcome('indeed nothing'))
print(empty_book.welcome)
doc = Document('a', 'b', 'c')
print(doc)
# 输出
# init function called
# Welcome! The context for this book is {}.
# 41
# Welcome! The context for this book is indeed nothing.
# Welcome! The context for this book is {}.
# init function called
# test class
继承
类的继承,顾名思义,指的是一个类既拥有另一个类的特征,也拥有不同于另一个类的独特特征。在这里的第一个类叫做子类,另一个叫做父类,特征其实就是类的属性和函数。
class Entity():
def __init__(self, object_type):
print('parent class init called')
self.object_type = object_type
def get_context_length(self):
raise Exception('get_context_length not implemented')
def print_title(self):
print(self.title)
class Document(Entity):
def __init__(self, title, author, context):
print('Document class init called')
Entity.__init__(self, 'document')
self.title = title
self.author = author
self.__context = context
def get_context_length(self):
return len(self.__context)
class Video(Entity):
def __init__(self, title, author, video_length):
print('Video class init called')
Entity.__init__(self, 'video')
self.title = title
self.author = author
self.__video_length = video_length
def get_context_length(self):
return self.__video_length
harry_potter_book = Document('Harry Potter(Book)', 'J. K. Rowling', 'Forever Do not believe any thing is capable of thinking independently ...')
harry_potter_movie = Video('Harry Potter(Movie)', 'J. K. Rowling', 120)
print(harry_potter_book.object_type)
print(harry_potter_movie.object_type)
harry_potter_book.print_title()
harry_potter_movie.print_title()
print(harry_potter_book.get_context_length())
print(harry_potter_movie.get_context_length())
########## 输出 ##########
# Document class init called
# parent class init called
# Video class init called
# parent class init called
# document
# video
# Harry Potter(Book)
# Harry Potter(Movie)
# 77
# 120
在这段代码中,Document
和 Video
它们有相似的地方,都有相应的标题、作者和内容等属性。可以从中抽象出一个叫做 Entity 的类,来作为它俩的父类。
需要注意的是构造函数。每个类都有构造函数,继承类在生成对象的时候,是不会自动调用父类的构造函数的,因此你必须在 init() 函数中显式调用父类的构造函数。它们的执行顺序是
子类的构造函数 -> 父类的构造函数
。需要注意父类
get_context_length()
函数。如果使用 Entity 直接生成对象,调用get_context_length()
函数,就会raise error
中断程序的执行。这其实是一种很好的写法,叫做函数重写,可以使子类必须重新写一遍get_context_length()
函数,来覆盖掉原有函数。注意到 print_title() 函数,这个函数定义在父类中,但是子类的对象可以毫无阻力地使用它来打印 title,这也就体现了继承的优势:减少重复的代码,降低系统的熵值(即复杂度)。
python 基础篇 类基础与继承的更多相关文章
- Python面向对象篇(2)-继承
在发表本篇随笔的时候,距离上一次发已经有一个多月了,很多朋友私信我为什么不持续更新了,在这里先跟大家说声抱歉.因为年底的工作较为繁重,实在分不出精力,更重要的也是在思考后面进阶的部分要按怎样的顺序写, ...
- iOS开发基础篇-Button基础
一.简单介绍 UIButton 的功能:响应用户操作.显示文字.显示图片.调整内部图片和文字的位置. 二. UIButton 的状态 UIControlStateNormal :普通状态,为默认情 ...
- python 3新式类的多继承
因为我用的是python3,所以所用到的类都是新式类,这里我说的都是新式类,python2类的继承复杂一些,主要有新式类和老式类.python3类(新式类)的继承是是广度优先(BFS),实例如下: c ...
- Python学习之路基础篇--08Python基础+ 文件的基本操作和 注册小作业
1 文件的基本操作 #1. 打开文件的模式有(默认为文本模式): r ,只读模式[默认模式,文件必须存在,不存在则抛出异常] w,只写模式[不可读:不存在则创建:存在则清空内容] a, 只追加写模式[ ...
- python基础篇_002_基础数据类型
Python基础数据类型 1.int # int 用于计算 num = 3 # int 与其他数据类型转换 int_to_str = str(num) # 数字加引号 print(int_to_str ...
- Python学习之路基础篇--02Python基础+小作业
1 变量 变量就是将一些运算的中间结果暂存到内存中,以便后续代码调用.必须由数字,字母,下划线任意组合,且不能数字开头.不能是python中的关键字,如['and', 'as', 'assert', ...
- python 网络篇(计算机网络基础)
计算机网络的发展及基础网络概念 广播 主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无 ...
- 新年在家学java之基础篇--类&方法
面向对象 面向对象OOP,面向过程POP 面向对象三大特征 封装 继承 多态 类 类由属性(对应类中的成员变量)和行为(成员方法)来构成 类的成员变量可以先声明,不用初始化,有默认值 方法名称如果多个 ...
- Python学习之路基础篇--10Python基础,函数进阶
1 命名空间 对于Python 来说命名空间一共有三种 1 内置命名空间 —— Python 解释器 就是Python 解释器一启动就可以使用的名字,储存在内置命名空间中.内置的名字在启动解释器的时候 ...
随机推荐
- POJ-3134-Power Calculus(迭代加深)
题意:输入一个n,问x从1次方开始,到n次方 ,可以乘或除已经计算出来的数 ,最少需要执行多少步? 思路:迭代加深 ,深度从0开始 ,直到返回值为真. 在深搜过程中剪枝(深度的判断 ,当前最大值尽全力 ...
- coding++:java-HashMap的负载因子为什么默认是0.75?
本篇文章基于JDK1.8,特在此说明 1):负载因子的作用 负载因子是和扩容机制有关的,意思是如果当前容器的容量,达到了我们设定的最大值,就要开始执行扩容操作.举个例子来解释,避免小白听不懂: 比如说 ...
- 《java编程思想》对象导论
1.抽象过程 所有编程语言都提供抽象机制.可以认为,人们所能够解决的问题的复杂性直接取决于抽象的类型和质量,所谓的'类型'是指“所抽象的是什么?”汇编语言是对底层机器的轻微抽象. java的基本 特性 ...
- 使用 Nginx 实现 301 跳转至 https 的根域名
基于 SEO 和安全性的考量,需要进行 301 跳转,以下使用 Nginx 作通用处理 实现结果 需要将以下地址都统一跳转到 https 的根域名 https://chanvinxiao.com ht ...
- PTA | 1008 数组元素循环右移问题 (20分)
一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...
- .NET Core项目部署到Linux(Centos7)(一)前言
目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...
- JAVABEAN的SCOPE属性(转载)
对于JSP 程序而言,使用JavaBeans 组件不仅可以封装许多信息,而且还可以将一些 数据处理的逻辑隐藏到JavaBeans 的内部,除此之外,我们还可以设定JavaBeans 的Scope ...
- Ubuntu16.04默认Python3.5升级Python3.6踩坑
好久没更新博客了,每天还是踩坑中.今天遇到第一个问题“ImportError: No module named 'secrets'”,导包是常见问题.这次的问题导致我又重装了一次环境,不过这是一个新服 ...
- scratch算立方根
10((1/3)lgx)=x(1/3)也就是立方根
- Spring(二):初始值赋值
依赖注入 1.构造器注入 见spring简介最后一大点. 2.Set方式注入 依赖注入:Set注入 依赖:bean对象的创建依赖于容器. 注入:bean对象的所有属性,由容器注入. bean ,里面属 ...