本节中将通过定义一些简单的 Python 类,来学习 Python 面向对象编程的基本概念。

定义类

在写你的第一个类之前,你应该知道它的语法。我们以下面这种方式定义类:

class nameoftheclass(parent_class):
statement1
statement2
statement3

在类的声明中你可以写任何 Python 语句,包括定义变量(在类中称为属性)、定义函数(在类中我们称为方法)。

>>> class MyClass(object):
... """A simple example class"""
... i = 12345
... def f(self):
... return 'hello world'

__init__方法

类的实例化使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类):

x = MyClass()

以上创建了一个新的类实例并将该对象赋给局部变量 x

这个实例化操作创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法,像下面这样:

def __init__(self):
self.data = []

类定义了 __init__() 方法的话,类的实例化操作会自动为新创建的类实例调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:

x = MyClass()

当然,出于弹性的需要,__init__() 方法可以有参数。事实上,参数通过__init__() 传递到类的实例化操作上。例如:

>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

继承

当一个类继承另一个类时,它将继承父类的所有功能(如变量和方法)。这有助于重用代码。

在下一个例子中我们首先创建一个叫做 Person 的类,然后创建两个派生类 Student 和 Teacher。当两个类都从 Person 类继承时,它们的类除了会有 Person 类的所有方法还会有自身用途的新方法和新变量。

代码写入文件 /home/shiyanlou/student_teacher.py

#!/usr/bin/env python3

class Person(object):
"""
返回具有给定名称的 Person 对象
""" def __init__(self, name):
self.name = name def get_details(self):
"""
返回包含人名的字符串
"""
return self.name class Student(Person):
"""
返回 Student 对象,采用 name, branch, year 3 个参数
""" def __init__(self, name, branch, year):
Person.__init__(self, name)
self.branch = branch
self.year = year def get_details(self):
"""
返回包含学生具体信息的字符串
"""
return "{} studies {} and is in {} year.".format(self.name, self.branch, self.year) class Teacher(Person):
"""
返回 Teacher 对象,采用字符串列表作为参数
"""
def __init__(self, name, papers):
Person.__init__(self, name)
self.papers = papers def get_details(self):
return "{} teaches {}".format(self.name, ','.join(self.papers)) person1 = Person('Sachin')
student1 = Student('Kushal', 'CSE', 2005)
teacher1 = Teacher('Prashad', ['C', 'C++']) print(person1.get_details())
print(student1.get_details())
print(teacher1.get_details())

运行程序:

shiyanlou:~/ $ ./student_teacher.py[17:34:31]
Sachin
Kushal studies CSE and is in 2005 year.
Prashad teaches c,c++.

在这个例子中你能看到我们是怎样在 Student 类和 Teacher 类中调用 Person 类的 __init__ 方法。

我们也在 Student 类和 Teacher 类中重写了 Person 类的 get_details() 方法。因此,当我们调用 student1 和 teacher1 的 get_details() 方法时,使用的是各自类(Student 和 Teacher)中定义的方法。

多继承

一个类可以继承自多个类,具有父类的所有变量和方法,语法如下:

class MyClass(Parentclass1, Parentclass2,...):
def __init__(self):
Parentclass1.__init__(self)
Parentclass2.__init__(self)
...
...

删除对象

现在我们已经知道怎样创建对象,现在我们来看看怎样删除一个对象。我们使用关键字 del 来做到这个。

>>> s = "I love you"
>>> del s
>>> s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 's' is not defined

del 实际上使对象的引用计数减少一,当对象的引用计数变成零的时候,垃圾回收器会删除这个对象。

属性(sttributes)读取方法

在 Python 里请不要使用属性(attributes)读取方法(getters和 setters)。如果你之前学过其它语言(比如 Java),你可能会想要在你的类里面定义属性读取方法。请不要这样做,直接使用属性就可以了,就像下面这样:

>>> class Student(object):
... def __init__(self, name):
... self.name = name
...
>>> std = Student("Kushal Das")
>>> print(std.name)
Kushal Das
>>> std.name = "Python"
>>> print(std.name)
Python

装饰器

你可能想要更精确的调整控制属性访问权限,你可以使用 @property 装饰器,@property 装饰器就是负责把一个方法变成属性调用的。

下面有个银行账号的例子,我们要确保没人能设置金额为负,并且有个只读属性 cny 返回换算人民币后的金额。

代码写入文件 /home/shiyanlou/property.py

#!/usr/bin/env python3

class Account(object):
"""账号类,
amount 是美元金额.
"""
def __init__(self, rate):
self.__amt = 0
self.rate = rate @property
def amount(self):
"""账号余额(美元)"""
return self.__amt @property
def cny(self):
"""账号余额(人民币)"""
return self.__amt * self.rate @amount.setter
def amount(self, value):
if value < 0:
print("Sorry, no negative amount in the account.")
return
self.__amt = value if __name__ == '__main__':
acc = Account(rate=6.6) # 基于课程编写时的汇率
acc.amount = 20
print("Dollar amount:", acc.amount)
print("In CNY:", acc.cny)
acc.amount = -100
print("Dollar amount:", acc.amount)

运行程序:

shiyanlou:~/ $ ./property.py
Dollar amount: 20
In CNY: 132.0
Sorry, no negative amount in the account.
Dollar amount: 20

总结

本实验我们了解了类的定义,类的继承以及多继承,并且最后我们还接触了装饰器这个概念,本质上,装饰器也是一种高阶函数。

参考链接:https://www.shiyanlou.com/courses/596

Python3简明教程(十一)—— 类的更多相关文章

  1. Python3 简明教程

    Python是由吉多·范罗苏姆(Guido Van Rossum)在90年代早期设计.它是如今最常用的编程 语言之一.它的语法简洁且优美,几乎就是可执行的伪代码. 注意:这篇教程是特别为Python3 ...

  2. Python3 简明教程学习(上)

    一.开始 Python 之旅交互模式 1.Ctrl + D 输入一个 EOF 字符来退出解释器,也可以键入 exit() 来退出 2.#!/usr/bin/env python3 中#!称为 Sheb ...

  3. Python3简明教程(十四)—— Collections模块

    collections 是 Python 内建的一个集合模块,提供了许多有用的集合类. 在这个实验我们会学习 Collections 模块.这个模块实现了一些很好的数据结构,它们能帮助你解决各种实际问 ...

  4. Python3简明教程(十二)—— 模块

    在这节我们将要学习 Python 模块相关知识.包括模块的概念和导入方法,包的概念和使用,第三方模块的介绍,命令行参数的使用等. 模块 到目前为止,我们在 Python 解释器中写的所有代码都在我们退 ...

  5. Python3简明教程(十)—— 异常

    在本节我们学习 Python 的异常以及如何在你的代码中处理它们. 异常 在程序执行过程中发生的任何错误都是异常.每个异常显示一些相关的错误信息,比如你在 Python3 中使用 Python2 独有 ...

  6. Python3简明教程(九)—— 文件处理

    文件是保存在计算机存储设备上的一些信息或数据.你已经知道了一些不同的文件类型,比如你的音乐文件,视频文件,文本文件.Linux 有一个思想是“一切皆文件”,这在实验最后的 lscpu 的实现中得到了体 ...

  7. Python3简明教程(六)—— 数据结构

    简单的来说,数据结构(data structure)是计算机中存储.组织数据的方式.比如我们之前使用过的列表就是一种数据结构,在这里我们还会深入学习它.之前也有简单的介绍. 列表 >>&g ...

  8. Python3简明教程(一)—— 开始Python之旅

    第一个Python程序 作为我们第一个Python程序——打印"Hello  World!". 在终端输入Python3进入交互界面: 输入print("Hello  W ...

  9. 实验楼-python3简明教程笔记

    #!/usr/bin/env python3 days = int(input("Enter days: ")) print("Months = {} Days = {} ...

随机推荐

  1. AutoIt获取Gridview中可以修改列的值

    有一个界面如上图:黑色框框部分是一个整体,也是一个gridview,如果我想把框框中右侧数据获取出来,该如何操作? 我尝试过了很多途径,都无法成功. 今天,我发现,当鼠标焦点在黑色框框左侧的部分的时候 ...

  2. laravel的核心概念:服务提供者provider解析

    我们知道laravel和核心就是一个IoC容器, 被称之为服务容器. 那么作为IoC容器, 就必须要有绑定对象生成器的工作.  在laravel中是服务提供者来项服务容器中绑定对象生成器的. 百牛信息 ...

  3. 中文环境下PostgreSQL的使用

    虽然官方文档有提到编码的问题,但是对于中文讲的比较简单,给中文的PostgreSQL用户带来很多困扰,本文简单简述一下中文环境下PostgreSQL如何正确设置编码. 一.服务器端的编码设置 Post ...

  4. linux的僵尸进程和孤儿进程

    1 僵尸进程: 子进程已经退出勒 但是还没有回收资源的进程为僵尸进程 代码验证 #include <stdio.h> #include <stdlib.h> #include ...

  5. ASP.NET Core MVC 2.x 全面教程__ASP.NET Core MVC 19. XSS & CSRF

    存库之前先净化,净化之后再提交到数据库 刚才插入的那笔数据 把默认的Razor引擎默认的EnCode去掉.Razor默认会开启htmlEnCodding 数据恢复回来 插入数据库之前对插入的数据进行净 ...

  6. eclipse快捷键设置

    文章斋词水电费 55 48 Eclipse中10个最有用的快捷键组合  一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开 ...

  7. hdu2476【区间DP,未完待续】

    好难搞得东西.... 题意都懒得写了,看题解的巨巨莫怪啊,未完待续未完待续,回去睡觉.

  8. 笔记:JavaScript闭包

    闭包 闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰.直观的说就是形成一个不销毁的栈环境. 对于闭包,当外部函数返回之后,内部函数依然可以访问外部函数的变量 ...

  9. Spring AOP SpringBoot集成

    上一篇文章<Spring AOP 面向切面编程入门>对AOP作了简要的介绍,包含一些专业术语的解释. 本文基于SpringBoot编写了一个简单的Spring AOPDemo. maven ...

  10. Spring Boot中使用Swagger2构建RESTful APIs介绍

    1.添加相关依赖 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <depen ...