掌握这些知识,你的python水平能更上一层楼(续)
笔者的上一篇python文章阅读量不错,看来python爱好者很多,所以再写一篇,以飨读者。
先接着上一篇讲一个问题,下面这段code有没有问题?
def countcalls(func):
count = 0
def wrapper(*args, **kwargs):
count += 1
print('num of calls: {}'.format(count))
return func(*args, **kwargs)
return wrapper @countcalls
def foo(x):
print (x+1) foo(1)
运行时会发现:
UnboundLocalError: local variable 'count' referenced before assignment
原因是count在wrapper下面除非global,不然是不可见的,那么就没有初始化了。但是这是不能加global的,因为它不是global,如果移出函数外,那么结果又不对了。怎么解决呢?
python3的解决方案:
nonlocal count
count += 1
python2的解决方案:
def countcalls(func):
def wrapper(*args, **kwargs):
wrapper.count += 1
print('num of calls: {}'.format(wrapper.count))
return func(*args, **kwargs)
wrapper.count = 0
return wrapper
基于class的decorator
class PrintLog:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print ('CALLING: {}'.format(self.func.__name__))
return self.func(*args, **kwargs)
主要是__call__决定的,任何object只要定义了__call__方法就能当函数用。下面对比一下:
class PrintLog:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print ('CALLING: {}'.format(self.func.__name__))
return self.func(*args, **kwargs) def printlog(func):
def wrapper(*args, **kwargs):
print("CALLING: " + func.__name__)
return func(*args, **kwargs)
return wrapper @printlog
def f(n):
return n+2 @PrintLog
def f_class(n):
return n+2
CALLING: f
5
CALLING: f_class
5
完全等效。__call__就相当于wrapper function
magic methods
相当于是python中的syntax sugar,让+,-,*,/啥的拿过来就用,举例如下:
class Angle:
def __init__(self, value):
self.value = value % 360
def __add__(self, other_angle):
return Angle(self.value + other_angle.value) a = Angle(45)
b = Angle(90)
c = a + b
print (c.value)
135
常用方法如下:
数学运算
__add__ a + b
__sub__ a - b
__mul__ a * b
__truediv__ a/b(浮点除)
__mod__ a % b
__pow__ a ** b
位运算
__lshift__ a << b
__rshift__ a >> b
__and__ a & b
__xor__ a ^ b
__or__ a | b
比较运算
__eq__ a == b
__ne__ a != b
__lt__ a < b
__le__ a <= b
__gt__ a > b
__ge__ a >= b
举个例子:
class Money(object):
def __init__(self, dollar, cent):
self.dollars = dollar
self.cents = cent
def __str__(self):
return "$" + str(self.dollars) + "." + "{:02}".format(self.cents)
def __repr__(self):
return "Money(" + str(self.dollars) + ", " + str(self.cents) + ")"
def __add__(self, other):
cents = (self.cents + other.cents) % 100
dollars = self.dollars + other.dollars + (self.cents + other.cents)/100
return Money(dollars, cents)
def __sub__(self, other):
if self.cents < other.cents:
cents = 100 + self.cents - other.cents
dollars = self.dollars - other.dollars - 1
else:
cents = self.cents - other.cents
dollars = self.dollars - other.dollars
return Money(dollars, cents)
def __mul__(self, other):
cents = (self.cents * other) % 100
dollars = self.dollars * other + (self.cents * other) / 100
return Money(dollars, cents)
def __eq__(self, other):
return self.dollars == other.dollars and self.cents == other.cents
def __ge__(self, other):
return self.dollars >= other.dollars and self.cents >= other.cents
def __lt__(self, other):
return self.dollars < other.dollars and self.cents < other.dollars
__str__和__repr__也是会时常用到的方法,它们都会放回string。__str__被用在print()时,同时str()也会调用它。而__repr__则是告诉你如何重现这个object,python命令行交互中输入object会调用__repr__,同时repr会调用它。
python collection类型
__getitem__相当于[index]
据两个例子大家就明白了,第一个例子是关于list,第二个例子是针对dict
class UniqueList:
def __init__(self, items):
self.items = []
for item in items:
self.append(item) def append(self, item):
if item not in self.items:
self.items.append(item) def __getitem__(self, index):
return self.items[index] ul = UniqueList([2,2,2,3,3,3,4,4,4]) print ul[0]
print ul[1]
print ul[2]
2
3
4
当然在具体实现的过程中对于index 要有input check,有问题需要raise IndexException,negative index要考虑语义的支持。
class MultiDict:
def __init__(self):
self.data = {} def insert(self, key, value):
if key not in self.data:
self.data[key] = []
self.data[key].append(value) def get_values(self, key):
return self.data[key] def get(self, key):
return self.get_values(key)[-1] def __getitem__(self, key):
return self.get_values(key)[-1] md = MultiDict()
md.insert("a", 1)
md.insert("a", 2)
print md['a']#2
Iterator
回到list那个例子,你觉得下面这个语法能够工作吗?
for i in ul:
print i
答:可以的,通过__getitem__我们不小心实现了iterator,事实上只要__getitem__能够接受0,1,2,... 并且在访问越界的时候raise IndexException,就相当于实现了iterator
Iterator的另一种实现是:
def __iter__(self):
return self def __next__(self):
...
raise StopIteration
return ...
可见__getitem__显得更简洁。
掌握这些知识,你的python水平能更上一层楼(续)的更多相关文章
- 掌握这些知识,你的python水平能更上一层楼
今天讲一些python中的高级用法,有助于大家更好的使用python这门语言.今天讲的这些知识是层层递进的关系,前面是后面的铺垫. 函数可变参数*args和**kwargs python支持固定参数, ...
- 机器学习算法的基本知识(使用Python和R代码)
本篇文章是原文的译文,然后自己对其中做了一些修改和添加内容(随机森林和降维算法).文章简洁地介绍了机器学习的主要算法和一些伪代码,对于初学者有很大帮助,是一篇不错的总结文章,后期可以通过文中提到的算法 ...
- 制作一个简单的部门员工知识分享的python抽取脚本
需求: 基于公司的文化和公司部门间以及员工之间的工作需求状态,或者想要了解某一些技能.专业方面的知识需求.促进并提高员工们的技能认知和技术水平. 详细代码如下: 先说一下存入csv表格的表头字段: 1 ...
- [Python][小知识][NO.2] Python 字符串跨行连接,或拆分为多行显示
1.前言 又是一个字符串很长,但又是一种格式的小字符串直接连接而成的大字符串. 这么我们拆成多行,即美感,又易于我们修改. 例如 文件选择框中的 通配符: wildcard = "Pytho ...
- 深入理解python(一)python语法总结:基础知识和对python中对象的理解
用python也用了两年了,趁这次疫情想好好整理下. 大概想法是先对python一些知识点进行总结,之后就是根据python内核源码来对python的实现方式进行学习,不会阅读整个源码,,,但是应该会 ...
- Python-turtle库知识小结(python绘图工具)
turtle:海龟(海龟库) Turtle库是Python语言中一个很流行的绘制图像的函数库 使用之前需要导入库:import turtle • turtle.setup(width,height,s ...
- 完整的正则表达式知识汇总(Python知识不断更新)
## 大纲: ## 一.正则概述 1.正则是什么 正则就是一套规则,或者语法 2.正则的作用 让我们判断是否符合我们的的规则,或者根据规则找到符合规则的数据 3.使用场景 可以用正则判断我们输入的邮箱 ...
- 【知识碎片】python 篇
领域:运维 网站 游戏 搜索 嵌入式 C/S软件 Openstack二次开发 绿色版:Portable Python 面向对象.解释型动态语言 env python 切换版也好使,自己寻找系统中pyt ...
- 剑指offer-左旋转字符串-知识迁移能力-python
题目描述汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”abcX ...
随机推荐
- 多项式A除以B
这个问题我是在PAT大区赛题里遇见的.题目如下: 多项式A除以B(25 分) 这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数 ...
- 故障定位之查找附近点GeoHash研讨
随着移动终端的普及,很多应用都基于LBS功能,附近的某某(餐馆.银行.妹纸等等). 基础数据中,一般保存了目标位置的经纬度:利用用户提供的经纬度,进行对比,从而获得是否在附近. 目标:查找附近的XXX ...
- 帮Python找“对象”
引言:你一定会感叹:Python还缺找对象? 毕竟"一切皆对象"是人家Python的哲学理念.不过,Python 允许程序员以纯粹的面向过程的方式来使用它,所以人们有时会忽视它那 ...
- Flex的 Event中属性currentTarget与target的区别
Flex的 Event中属性currentTarget与target的区别 1.区别 (1)currentTarget是事件的处理对象(event processor) (2)target是事件的调用 ...
- web开发中对缓存的使用
很久没有发表随笔了,最近工作不是太忙,抽点时间 给大家谈谈缓存吧 ; 在我从事web开发的几年实践中 接触了缓存技术 也是比较多的,在最初的 项目当中 我们用到 hibernate 的 一二级缓存, ...
- WKWebView 加载本地HTML显示不出网页问题,这点你注意了吗?-------完美显示
1.首先,WKWebView的引入和创建,我这里就不做阐述,我要说的,就是解决别人不能给您解决的问题 2.WKWebView 加载本地HTML,也就是两三句代码 是吧?作为读者的您肯定也知道,也实现 ...
- 第二篇:数据可视化 - 基本API
前言 数据可视化是数据挖掘非常重要的一个环节,它不单在查阅了解数据环节使用到,在整个数据挖掘的流程中都会使用到. 因为数据可视化不单可以形象地展示数据,让你对数据有更好的总体上的了解,而且还可以让你清 ...
- Java双等号,Equals(),HashCode()小结
默认情况 - 双等号==,比较的是内存地址. - equals(),默认比较的是内存地址. - hashCode(),默认返回的是object的内存地址. String中方法改写的情况 经常会遇到需要 ...
- [Luogu2617]Dynamic Ranking
题面戳这 类似算法总结 1.静态整体Kth 滑稽吧...sort一遍就好了. 时间复杂度\(O(nlogn)\) 空间复杂度\(O(n)\) 2.动态整体Kth 离散化后开一棵权值线段树,每个位置的值 ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...