翻译:《实用的Python编程》07_05_Decorated_methods
目录 | 上一节 (7.4 装饰器) | 下一节 (8 测试和调试)
7.5 装饰方法
本节讨论一些与方法定义结合使用的内置装饰器。
预定义的装饰器
在类定义中,有许多预定义的装饰器用于指定特殊类型的方法。
class Foo:
def bar(self,a):
...
@staticmethod
def spam(a):
...
@classmethod
def grok(cls,a):
...
@property
def name(self):
...
让我们逐个查看吧。
静态方法
@staticmethod 用于定义所谓的静态类方法( static class method,来自于 C++/Java)。静态方法是一个函数,这个函数是类的一部分,但不是在实例上进行操作。
class Foo(object):
@staticmethod
def bar(x):
print('x =', x)
>>> Foo.bar(2)
x=2
>>>
静态方法有时用于实现类的内部支持代码,例如,用于帮助管理已创建的实例(内存管理,系统资源,持久化,锁等等)。有时也用于某些设计模式(这里暂不讨论)。
类方法
@classmethod 用于定义类方法(class methods)。类方法是一种将 类 对象而不是实例作为第一个参数的方法。
class Foo:
def bar(self):
print(self)
@classmethod
def spam(cls):
print(cls)
>>> f = Foo()
>>> f.bar()
<__main__.Foo object at 0x971690> # The instance `f`
>>> Foo.spam()
<class '__main__.Foo'> # The class `Foo`
>>>
类方法常用作定义替代构造函数(constructor)的工具。
import time
class Date:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
@classmethod
def today(cls):
# Notice how the class is passed as an argument
tm = time.localtime()
# And used to create a new instance
return cls(tm.tm_year, tm.tm_mon, tm.tm_mday)
d = Date.today()
类方法可以和继承等特性一起使用以解决棘手的问题。
class Date:
...
@classmethod
def today(cls):
# Gets the correct class (e.g. `NewDate`)
tm = time.localtime()
return cls(tm.tm_year, tm.tm_mon, tm.tm_mday)
class NewDate(Date):
...
d = NewDate.today()
练习
练习 7.11:实践中的类方法
在 report.py 和 portfolio.py 文件中, Portfolio 类的创建稍微有点混乱。例如,report.py 程序具有如下代码:
def read_portfolio(filename, **opts):
'''
Read a stock portfolio file into a list of dictionaries with keys
name, shares, and price.
'''
with open(filename) as lines:
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
portfolio = [ Stock(**d) for d in portdicts ]
return Portfolio(portfolio)
且 portfolio.py 文件中定义的 Portfolio 具有一个奇怪的初始化:
class Portfolio:
def __init__(self, holdings):
self.holdings = holdings
...
坦白说,因为代码分散在各文件中,所以责任链稍微有点混乱。如果 Portfolio 类应该包含 Stock 类的实例列表,那么你应该修改该类以使其更清晰。示例:
# portfolio.py
import stock
class Portfolio:
def __init__(self):
self.holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self.holdings.append(holding)
...
如果想要从 CSV 文件中读取投资组合数据,那么你也许应该为此创建一个类方法:
# portfolio.py
import fileparse
import stock
class Portfolio:
def __init__(self):
self.holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self.holdings.append(holding)
@classmethod
def from_csv(cls, lines, **opts):
self = cls()
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
for d in portdicts:
self.append(stock.Stock(**d))
return self
要使用新的 Portfolio 类,你可以这样编写代码:
>>> from portfolio import Portfolio
>>> with open('Data/portfolio.csv') as lines:
... port = Portfolio.from_csv(lines)
...
>>>
请对 Portfolio 类进行修改,然后修改 report.py 的代码以使用类方法。
目录 | 上一节 (7.4 装饰器) | 下一节 (8 测试和调试)
注:完整翻译见 https://github.com/codists/practical-python-zh
翻译:《实用的Python编程》07_05_Decorated_methods的更多相关文章
- 翻译:《实用的Python编程》InstructorNotes
实用的 Python 编程--讲师说明 作者:戴维·比兹利(David Beazley) 概述 对于如何使用我的课程"实用的 Python 编程"进行教学的问题,本文档提供一些通用 ...
- 翻译:《实用的Python编程》README
欢迎光临 大约 25 年前,当我第一次学习 Python 时,发现 Python 竟然可以被高效地应用到各种混乱的工作项目上,我立即被震惊了.15 年前,我自己也将这种乐趣教授给别人.教学的结果就是本 ...
- 翻译:《实用的Python编程》05_02_Classes_encapsulation
目录 | 上一节 (5.1 再谈字典) | 下一节 (6 生成器) 5.2 类和封装 创建类时,通常会尝试将类的内部细节进行封装.本节介绍 Python 编程中有关封装的习惯用法(包括私有变量和私有属 ...
- 翻译:《实用的Python编程》04_02_Inheritance
目录 | 上一节 (4.1 类) | 下一节 (4.3 特殊方法) 4.2 继承 继承(inheritance)是编写可扩展程序程序的常用手段.本节对继承的思想(idea)进行探讨. 简介 继承用于特 ...
- 翻译:《实用的Python编程》01_02_Hello_world
目录 | 上一节 (1.1 Python) | 下一节 (1.3 数字) 1.2 第一个程序 本节讨论有关如何创建一个程序.运行解释器和调试的基础知识. 运行 Python Python 程序始终在解 ...
- 翻译:《实用的Python编程》03_03_Error_checking
目录 | 上一节 (3.2 深入函数) | 下一节 (3.4 模块) 3.3 错误检查 虽然前面已经介绍了异常,但本节补充一些有关错误检查和异常处理的其它细节. 程序是如何运行失败的 Python 不 ...
- 翻译:《实用的Python编程》03_04_Modules
目录 | 上一节 (3.3 错误检查) | 下一节 (3.5 主模块) 3.4 模块 本节介绍模块的概念以及如何使用跨多个文件的函数. 模块和导入 任何一个 Python 源文件都是一个模块. # f ...
- 翻译:《实用的Python编程》03_05_Main_module
目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论) 3.5 主模块 本节介绍主程序(主模块)的概念 主函数 在许多编程语言中,存在一个主函数或者主方法的概念. // c / c++ ...
- 翻译:《实用的Python编程》04_01_Class
目录 | 上一节 (3.6 设计讨论) | 下一节 (4.2 继承) 4.1 类 本节介绍 class 语句以及创建新对象的方式. 面向对象编程(OOP) 面向对象编程是一种将代码组织成对象集合的编程 ...
随机推荐
- 离场定高转弯DF与CF的对比
也许是刚学会CAD的缘故,配合风螺旋插件,画图的感觉真是蛮爽的,忍不住画了一张又一张. 接着昨天的离场保护区,我们来聊一下PBN指定高度转弯保护区的画法.指定高度转弯的计算本身没有太多复杂的地方,真正 ...
- redis源码之dict
大家都知道redis默认是16个db,但是这些db底层的设计结构是什么样的呢? 我们来简单的看一下源码,重要的字段都有所注释 typedef struct redisDb { dict *dict; ...
- epoll原理详解及epoll反应堆模型
本文转载自epoll原理详解及epoll反应堆模型 导语 设想一个场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收TCP包),也就是说在每一时刻 ...
- C#使用OpenCV剪切图形中的人物头像
前言 本文主要介绍如何使用OpenCV剪切图形中的人物头像. 准备工作 首先创建一个Wpf项目--OpenCV_Face_Wpf,这里版本使用Framework4.7.2. 然后使用Nuget搜索[E ...
- idea配置阿里maven镜像
首先打开IDEA安装路径下的:"\plugins\maven\lib\maven3\conf\settings.xml" 找到里面的mirror配置,进行修改如下: <mir ...
- MySQL5.7.29 和 Navicat ===> windows窗口式按装和使用
MySQL windows窗口式按装下载方法:官网: https://www.mysql.com/ ==> DOWNLOADS ==> MySQL Community (GPL) Down ...
- MySQL学习笔记(六)
好耶,七天课程的最后一天!我当然还没精通了,,,之后可能是多练习题目然后再学学其他的东西吧.mysql新的知识点也会在后面补充的. 一.杂七杂八补充 1. 当多个函数共用同样的参数时,可以转变成类进行 ...
- Synchronized 轻量级锁会自旋?好像并不是这样的。
本来是在写面霸系列的,写着写着就写到了这一题: Synchronized 原理知道不? 而关于 Synchronized 我去年还专门翻阅 JVM HotSpot 1.8 的源码来研究了一波,那时候我 ...
- MVC base64加密的文件,前端下载
后端代码: public FileResult OutPutFile(string base64file,string filename) { buffer = Convert.FromBase64 ...
- Reincarnation Without New Body(RWNB): Basic Theory and Baseline 现世转生基本理论及简单操作
Abstract 投胎学是一门高深的学问,不仅没有现存的理论,也没有过往的经验.根据种种猜测,投胎后前世的记忆也不能保留,造成了很大的不方便.在本文中,我们绕过了投胎需要"来世"的 ...