重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

包含python实现工厂函数的词条

Python中冷门但非常好用的内置函数

Python中有许多内置函数,不像print、len那么广为人知,但它们的功能却异常强大,用好了可以大大提高代码效率,同时提升代码的简洁度,增强可阅读性

创新互联主要从事成都网站建设、成都网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务沈丘,十多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108

Counter

collections在python官方文档中的解释是High-performance container datatypes,直接的中文翻译解释高性能容量数据类型。这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。在python3.10.1中它总共包含以下几种数据类型:

容器名简介

namedtuple() 创建命名元组子类的工厂函数

deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)

ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面

Counter 字典的子类,提供了可哈希对象的计数功能

OrderedDict 字典的子类,保存了他们被添加的顺序

defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值

UserDict 封装了字典对象,简化了字典子类化

UserList 封装了列表对象,简化了列表子类化

UserString 封装了字符串对象,简化了字符串子类化

其中Counter中文意思是计数器,也就是我们常用于统计的一种数据类型,在使用Counter之后可以让我们的代码更加简单易读。Counter类继承dict类,所以它能使用dict类里面的方法

举例

#统计词频

fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']

result = {}

for fruit in fruits:

if not result.get(fruit):

result[fruit] = 1

else:

result[fruit] += 1

print(result)

#{'apple': 2, 'peach': 3, 'lemon': 1}下面我们看用Counter怎么实现:

from collections import Counter

fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']

c = Counter(fruits)

print(dict(c))

#{'apple': 2, 'peach': 3, 'lemon': 1}显然代码更加简单了,也更容易阅读和维护了。

elements()

返回一个迭代器,其中每个元素将重复出现计数值所指定次。元素会按首次出现的顺序返回。如果一个元素的计数值小于1,elements()将会忽略它。

c = Counter(a=4, b=2, c=0, d=-2)

sorted(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']most_common([n])

返回一个列表,其中包含n个最常见的元素及出现次数,按常见程度由高到低排序。如果n被省略或为None,most_common()将返回计数器中的所有元素。计数值相等的元素按首次出现的顺序排序:

Counter('abracadabra').most_common(3)

[('a', 5), ('b', 2), ('r', 2)]这两个方法是Counter中最常用的方法,其他方法可以参考 python3.10.1官方文档

实战

Leetcode 1002.查找共用字符

给你一个字符串数组words,请你找出所有在words的每个字符串中都出现的共用字符(包括重复字符),并以数组形式返回。你可以按任意顺序返回答案。

输入:words = ["bella", "label", "roller"]

输出:["e", "l", "l"]

输入:words = ["cool", "lock", "cook"]

输出:["c", "o"]看到统计字符,典型的可以用Counter完美解决。这道题是找出字符串列表里面每个元素都包含的字符,首先可以用Counter计算出每个元素每个字符出现的次数,依次取交集最后得出所有元素共同存在的字符,然后利用elements输出共用字符出现的次数

class Solution:

def commonChars(self, words: List[str]) - List[str]:

from collections import Counter

ans = Counter(words[0])

for i in words[1:]:

ans = Counter(i)

return list(ans.elements())提交一下,发现83个测试用例耗时48ms,速度还是不错的

sorted

在处理数据过程中,我们经常会用到排序操作,比如将列表、字典、元组里面的元素正/倒排序。这时候就需要用到sorted(),它可以对任何可迭代对象进行排序,并返回列表

对列表升序操作:

a = sorted([2, 4, 3, 7, 1, 9])

print(a)

# 输出:[1, 2, 3, 4, 7, 9]对元组倒序操作:

sorted((4,1,9,6),reverse=True)

print(a)

# 输出:[9, 6, 4, 1]使用参数:key,根据自定义规则,按字符串长度来排序:

fruits = ['apple', 'watermelon', 'pear', 'banana']

a = sorted(fruits, key = lambda x : len(x))

print(a)

# 输出:['pear', 'apple', 'banana', 'watermelon']all

all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。元素除了是 0、空、None、False外都算True。注意:空元组、空列表返回值为True。

all(['a', 'b', 'c', 'd']) # 列表list,元素都不为空或0

True

all(['a', 'b', '', 'd']) # 列表list,存在一个为空的元素

False

all([0, 1,2, 3]) # 列表list,存在一个为0的元素

False

all(('a', 'b', 'c', 'd')) # 元组tuple,元素都不为空或0

True

all(('a', 'b', '', 'd')) # 元组tuple,存在一个为空的元素

False

all((0, 1, 2, 3)) # 元组tuple,存在一个为0的元素

False

all([]) # 空列表

True

all(()) # 空元组

Trueany函数正好和all函数相反:判断一个tuple或者list是否全为空,0,False。如果全为空,0,False,则返回False;如果不全为空,则返回True。

F-strings

在python3.6.2版本中,PEP 498提出一种新型字符串格式化机制,被称为 “字符串插值” 或者更常见的一种称呼是F-strings,F-strings提供了一种明确且方便的方式将python表达式嵌入到字符串中来进行格式化:

s1='Hello'

s2='World'

print(f'{s1} {s2}!')

# Hello World!在F-strings中我们也可以执行函数:

def power(x):

return x*x

x=4

print(f'{x} * {x} = {power(x)}')

# 4 * 4 = 16而且F-strings的运行速度很快,比传统的%-string和str.format()这两种格式化方法都快得多,书写起来也更加简单。

本文主要讲解了python几种冷门但好用的函数,更多内容以后会陆陆续续更新~

闭包/工厂函数

闭包:python函数的内部的变量离开这个函数就失去了作用域而不复存在

但是嵌套函数可以!

解析: x是属于fn1函数的,但是在 fn1()调用结束后 我们又加了两个括号调用到了fn3,你看他还是能输出x的值

但嵌套函数只是引用它!不能修改它,要在嵌套函数里修改x的值需要申明nonlocal x

工厂函数:

函数return的时候返回一个函数名

参考: 石溪的答案

python大神,大神进,关于对象,cmp规则,工厂函数问题

1、列表对象是list类的实例化对象,list类的基类是object

isinstance(l,list)

True

issubclass(list,object)

True

2、cmp的跨类型比较,这里我找到的一段文字

1.   对两个列表的元素进行比较.

2.   如果比较的元素是同类型的,则比较其值,返回结果.

3.   如果两个元素不是同一种类型,则检查它们是否是数字.

a. 如果是数字,执行必要的数字强制类型转换,然后比较.

b. 如果有一方的元素是数字,则另一方的元素"大"(数字是"最小的")

c. 否则,通过类型名字的字母顺序进行比较.

4.   如果有一个列表首先到达末尾,则另一个长一点的列表"大".

5.   如果我们用尽了两个列表的元素而且所有元素都是相等的,那么结果就是个平局,就

是说返回一个 0.

3、关于工厂函数的定义,可以看看这里:

最好参照实例自己做一做,比较容易弄懂

4、列出所有内置函数的方法我也不知道,感觉也太多了。

享学课堂浅谈Python序列内建函数都有哪些

1、Python类型操作符和内建函数总结

表4.5列出了所有操作符和内建函数,其中操作符顺序是按优先级从高到低排列的。同一种灰度的操作符拥有同样的优先级。注意在operator模块中有这些(和绝大多数Python)操作符相应的同功能的函数可供使用。

表4.5 标准类型操作符和内建函数

操作符/函数

描 述

结 果a

字符串表示

``

对象的字符串表示

str

内建函数

cmp(obj1, obj2)

比较两个对象

int

repr(obj)

对象的字符串表示

str

str(obj)

对象的字符串表示

str

type(obj)

检测对象的类型

type

值比较

小于

bool

大于

bool

=

小于或等于

bool

=

大于或等于

bool

==

等于

bool

!=

不等于

bool

不等于

bool

对象比较

is

bool

is not

不是

bool

布尔操作符

not

逻辑反

bool

and

逻辑与

bool

or

逻辑或

bool

2、Python数值类型操作符和内建函数

一、工厂函数

数值工厂函数总结类(工厂函数) 操作

bool(obj) b 返回obj对象的布尔值,也就是 obj.__nonzero__()方法的返回值。

int(obj, base=10)   返回一个字符串或数值对象的整数表 示, 类似string.atoi();

从Python 1.6起, 引入了可选的进制参数。

long(obj, base=10) 返回一个字符或数据对象的长整数表 示,类似string.atol(),

从Python1.6起, 引入了可选的进制参数 float(obj) ,

返回一个字符串或数据对象的浮点数 表示,类似string.atof()。

complex(str) or返回一个字符串的复数表示,或 者根据给定的实数,

complex(real, imag=0.0)  (及一个可选 的虚数部分)生成一个复数对象。

二、内建函数

1、分类

Python 有五个运算内建函数用于数值运算:

abs(num), coerce(num1,num2), divmod(num1,num2), pow(num1,num2,mod=1)和 round(flt,ndig=0)

其中abs()返回给定参数的绝对值。如果参数是一个复数, 那么就返回math.sqrt(num.real2 + num.imag2).

coerce()是一个数据类型转换函数,不过它的行为更像一个运算符.数coerce()为程序员提供了不依赖Python 解释器,而是自定义两个数值类型转换的方法。对一种新创建的数值类型来说, 这个特性非常有用.函数coerce()仅返回一个包含类型转换完毕的两个数值元素的元组.

divmod()内建函数把除法和取余运算结合起来, 返回一个包含商和余数的元组.对整数来说,它的返回值就是地板除和取余操作的结果.对浮点数来说,返回的商部分是math.floor(num1/num2),对复数来说,商部分是ath.floor((num1/num2).real).

pow()它和双星号 (**)运算符都可以进行指数运算.不过二者的区别并不仅仅在于一个是运算符,一个是内建函数.在Python 1.5 之前,并没有 ** 运算符,内建函数pow()还接受第三个可选的参数,一个余数参数.如果有这个参数的, pow() 先进行指数运算,然后将运算结果和第三个参数进行取余运算.这个特性主要用于密码运算,并且比 pow(x,y) % z 性能更好, 这是因为这个函数的实现类似于C 函数pow(x,y,z).

round()用于对浮点数进行四舍五入运算。它有一个可选的小数位数参数.如果不提供小数位参数, 它返回与第一个参数最接近的整数(但仍然是浮点类型).第二个参数告诉round 函数将结果精确到小数点后指定位数.

2、函数int()/round()/math.floor()它们之间的不同之处:

函数 int()直接截去小数部分.(返回值为整数)

函数 floor() 得到最接近原数但小于原数的整数.(返回值为浮点数)

函数 round() 得到最接近原数的整数.(返回值为浮点数)

3、进制转换函数:

返回字符串表示的8 进制和16 进制整数,它们分别是内建函数:

oct()和 hex(). oct(255)='0377'/hex(255)='0xff'

函数chr()接受一个单字节整数值(0到255),返回一个字符串(ASCII),其值为对应的字符.chr(97)='a'

函数ord()则相反,它接受一个字符(ASCII 或 Unicode),返回其对应的整数值.ord('A')=65

3、Python字符串函数

(一)标准类型操作符和标准内建函数

1)、标准类型操作符

,,=,=,==,!=,对象值得比较

注:做比较时字符串是按ASCII值的大小来比较的

is 对象身份比较

and,or,not 布尔类型

2)标准内建函数

type(obj)

cmp(obj1,obj2)

str(obj)和repr(obj) 或反引号运算符(``) 可以方便的以字符串的方式获取对象的

内容、类型、数值属性等信息。str()函数得到的字符串可读性好, 而repr()函数得到的字符

串通常可以用来重新获得该对象, 通常情况下 obj == eval(repr(obj)) 这个等式是成立的

isinstance(obj,type) 判断对象的类型

(二)序列操作

1、序列操作

字符串属于序列对象,可以使用所有序列的操作和函数

切片 [] [:] [::]

简单总结:

*索引(S[i])获取特定偏移的元素。

——第一个元素偏移为0

——(S[0])获取第一个元素。

——负偏移索引意味着从最后或右边反向进行计数

——(S[-2])获取倒数第二个元素(就像S[len(s)-2]一样

*分片[S[i:j]提取对应的部分作为一个序列

——右边界不包含在内

——分片的边界默认为0和序列的长度,如果没有给出的话S[:]

——(S[1:3])获取了从偏移为1,直到但不包括偏移为3的元素

——(S[1:])获取从偏移为1到末尾之间的元素

——(S[:3])获取从偏移为0直到但不包括偏移为3的元素

——(S[:-1])获取从偏移为0直到但不包括最后一个元素之间的元素

——(S[:])获取从偏移为0到末尾之间的元素,这有效地实现了顶层S拷贝

拷贝了一个相同值,但是是不同内存区域的对象。对象字符串这样不可变的对象不是很有用,但是对于可以实地修改的对象来说很有用。

比如列表。

扩展分片:第三个限制值 【步进】

完整形式:X[I:J:K]:这标识索引X对象的元素,从偏移为I直到J-1,每隔K元素索引一次。第三个限制值,K,默认为1

实例

Python Code

1

2

3

4

5

S='abcdefghijk'

S[1:10]

'bcdefghij'

S[1:10:2]

'bdfhj

也可以使用负数作为步进。

分片表达式

Python Code

1

2

"hello"[::-1]

'olleh'

通过负数步进,两个边界的意义实际上进行了反转。

3、成员操作符 in ,not in

返回布尔值True 或False

可以使用string模块来判断输入字符的合法性,可见成品中的idcheck.py

4、字符串连接

+ 连接字符串 ‘name’+' '+'jin'

字符串格式化 '%s %s' % ('name','jin')

join()方法 ' '.join(('name','jin')) ' '.join(['name','jin'])

5、删除清空字符串

del aString

aString=''

(三)、序列函数

序列类型函数

len(str) 返回字串的长度

enumerate(iter):接受一个可迭代对象作为参数,返回一个enumerate

max(str)/min(str):max()和min()函数对其他的序列类型可能更有用,但对于string类型它们能很好地运行,返回最大或者最小的字符(按照ASCII 码值排列),

zip([it0, it1,... itN]) 返回一个列表,其第一个元素是it0,it1,...这些元素的第一个元素组成的一个元组,第二个...,类推.

reversed(seq)c 接受一个序列作为参数,返回一个以逆序访问的迭代器(PEP 322)

sorted(iter,func=None,key=None,reverse=False) 接受一个可迭代对象作为参数,返回一个有序的列表;可选参数func,key 和reverse 的含义跟list.sort()内建函数的参数含义一样.

注意:

sorted等需要在原处修改的函数无法用在字符串对象,但可以产生新的对象

sum处理的对象是数字,不能用在字符串

sorted(s)

['a', 'e', 'e', 'g', 'g', 'g', 'o']

(四)只适合于字符串类型的函数

1)raw_input()函数

内建的raw_input()函数使用给定字符串提示用户输入并将这个输入返回,下面是一个使

用raw_input()的例子:

user_input = raw_input("Enter your name: ")

prin user_input

2)str() and unicode()

str()和unicode()函数都是工厂函数,就是说产生所对应的类型的对象.它们接受一个任

意类型的对象,然后创建该对象的可打印的或者Unicode 的字符串表示. 它们和basestring 都

可以作为参数传给isinstance()函数来判断一个对象的类型

3)chr(), unichr(), and ord()

chr()函数用一个范围在range(256)内的(就是0 到255)整数做参数,返回一个对应的字符.unichr()跟它一样,只不过返回的是Unicode 字符

ord()函数是chr()函数(对于8 位的ASCII 字符串)或unichr()函数(对于Unicode 对象)

的配对函数,它以一个字符(长度为1 的字符串)作为参数,返回对应的ASCII 数值,或者Unicode

数值,如果所给的Unicode 字符超出了你的Python 定义范围,则会引发一个TypeError 的异常

(五)、只适用于字符串的操作符

1、格式化操作符 %

字符串格式化符号

格式化字符 转换方式

%c 转换成字符(ASCII 码值,或者长度为一的字符串)

%ra 优先用repr()函数进行字符串转换

%s 优先用str()函数进行字符串转换

%d / %i 转成有符号十进制数

%ub 转成无符号十进制数

%ob 转成无符号八进制数

%xb/%Xb (Unsigned)转成无符号十六进制数(x/X 代表转换后的十六进制字符的大

小写)

%e/%E 转成科学计数法(e/E 控制输出e/E)

%f/%F 转成浮点数(小数部分自然截断)

%g/%G %e 和%f/%E 和%F 的简写

%% 输出%

格式化操作符辅助指令

符号 作用

* 定义宽度或者小数点精度

- 用做左对齐

+ 在正数前面显示加号( + )

sp 在正数前面显示空格

# 在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于

用的是'x'还是'X')

0 显示的数字前面填充‘0’而不是默认的空格

% '%%'输出一个单一的'%'

(var) 映射变量(字典参数)

m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

2、字符串模板: 更简单的替代品

由于新式的字符串Template 对象的引进使得string 模块又重新活了过来,Template 对象

有两个方法,substitute()和safe_substitute().前者更为严谨,在key 缺少的情况下它会报一

个KeyError 的异常出来,而后者在缺少key 时,直接原封不动的把字符串显示出

3、原始字符串操作符( r/R )

字符串抑制转义r'带特殊符号的字串'

myfile=open(r'C:\new\text.data','w')

4、Unicode 字符串操作符( u/U )

u'abc' U+0061 U+0062 U+0063

u'\u1234' U+1234

u'abc\u1234\n' U+0061 U+0062 U+0063 U+1234 U+0012

(六)字符串对象的方法:

1、删减

T2.lstrip() 移除字符串前面字符(默认空格),返回字符串

T2.rstrip() 移除字符串后面字符(默认空格),返回字符串

T2.strip() 移除字符串前后面空格,返回字符串 默认空格,可以其他字符 S.strip('"')

2、切割

partition(sep),

rpartition(sep),

splitlines([keepends]),#把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符

split([sep [,maxsplit]]),#以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符

rsplit([sep[,maxsplit]]) #从右到左切割

备注:

partition()函数族是2.5版本新增的方法。它接受一个字符串参数,并返回一个3个元素的 tuple 对象。

如果sep没出现在母串中,返回值是 (sep, ‘’, ‘’);

否则,返回值的第一个元素是 sep 左端的部分,第二个元素是 sep 自身,第三个元素是 sep 右端的部分。

S.partition(';')

('', ';', ' generated by /sbin/dhclient-script\nnameserver 172.16.10.171\nnameserver 8.8.8.8\nnameserver 172.16.0.2\nnameserver 178.79.131.110\nnameserver 202.96.199.133\n')

参数 maxsplit 是分切的次数,即最大的分切次数,所以返回值最多有 maxsplit+1 个元素。

s.split() 和 s.split(‘ ‘)的返回值不尽相同

' hello world!'.split()

['hello', 'world!']

' hello world!'.split(' ')

['', '', 'hello', '', '', 'world!']

S.split('\n',3)

['; generated by /sbin/dhclient-script', 'nameserver 172.16.10.171', 'nameserver 8.8.8.8', 'nameserver 172.16.0.2\nnameserver 178.79.131.110\nnameserver 202.96.199.133\n']

超过最大切割个数后面的全部为一个元素

按行切割

S

'; generated by /sbin/dhclient-script\nnameserver 172.16.10.171\nnameserver 8.8.8.8\nnameserver 172.16.0.2\nnameserver 178.79.131.110\nnameserver 202.96.199.133\n'

S.splitlines()

['; generated by /sbin/dhclient-script', 'nameserver 172.16.10.171', 'nameserver 8.8.8.8', 'nameserver 172.16.0.2', 'nameserver 178.79.131.110', 'nameserver 202.96.199.133']

产生差异的原因在于当忽略 sep 参数或sep参数为 None 时与明确给 sep 赋予字符串值时 split() 采用两种不同的算法。

对于前者,split() 先去除字符串两端的空白符,然后以任意长度的空白符串作为界定符分切字符串

即连续的空白符串被当作单一的空白符看待;

对于后者则认为两个连续的 sep 之间存在一个空字符串。因此对于空字符串(或空白符串),它们的返回值也是不同的:

''.split()

[]

''.split(' ')

['']

3、变形

lower(),#全部小写

upper(),#全部小写

capitalize(),#首字母大写

swapcase(),#大小写交换

title()#每个单词第一个大写,其他小写

备注

因为title() 函数并不去除字符串两端的空白符也不会把连续的空白符替换为一个空格,

所以建议使用string 模块中的capwords(s)函数,它能够去除两端的空白符,再将连续的空白符用一个空格代替。

Python Code

1

2

3

4

' hello world!'.title()

' Hello World!'

string.capwords(' hello world!')

'Hello World!'

4、连接

join(seq)

join() 函数的高效率(相对于循环相加而言),使它成为最值得关注的字符串方法之一。

它的功用是将可迭代的字符串序列连接成一条长字符串,如:

conf = {'host':'127.0.0.1',

... 'db':'spam',

... 'user':'sa',

... 'passwd':'eggs'}

';'.join("%s=%s"%(k, v) for k, v in conf.iteritems())

'passswd=eggs;db=spam;user=sa;host=127.0.0.1'

S=''.join(T) #使用空字符串分割把字符列表转换为字符串

5、查找

count( sub[, start[, end]]),#计算substr在S中出现的次数

find( sub[, start[, end]]),#返回S中出现sub的第一个字母的标号,如果S中没有sub则返回-1。start和end作用就相当于在S[start:end]中搜索

index( substr[, start[, end]]),#与find()相同,只是在S中没有substr时,会返回一个运行时错误

rfind( sub[, start[,end]]),#返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号

rindex( sub[, start[, end]])

T2.find('ie') 字符串方法调用:搜索

find()----找到的第一个符合字符的index

rfind()-----找到最后一个符合的字符的index

备注:

find()函数族找不到时返回-1,index()函数族则抛出ValueError异常。

另,也可以用 in 和 not in 操作符来判断字符串中是否存在某个模板

6、替换

replace(old, new[,count]),#把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换

translate(table[,deletechars]) #使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉

备注:

replace()函数的 count 参数用以指定最大替换次数

translate() 的参数 table 可以由 string.maketrans(frm, to) 生成

translate() 对 unicode 对象的支持并不完备,建议不要使用

7、判定

isalnum(),#是否全是字母和数字,并至少有一个字符

isalpha(),是否全是字母,并至少有一个字符

isdigit(),是否全是数字,并至少有一个字符 ,如果是全数字返回True,否则返回False

islower(),#S中的字母是否全是小写

isupper(),#S中的字母是否是大写

isspace(),#是否全是空白字符,并至少有一个字符

istitle(),S是否是首字母大写的

startswith(prefix[, start[, end]]), #是否以prefix开头

endswith(suffix[,start[, end]]),#以suffix结尾

备注:

这些函数都比较简单,顾名知义。需要注意的是*with()函数族可以接受可选的 start, end 参数,善加利用,可以优化性能。

另,自 Py2.5 版本起,*with() 函数族的 prefix 参数可以接受 tuple 类型的实参,当实参中的某人元素能够匹配,即返回 True。

8、填充

字符串在输出时的对齐:

center(width[, fillchar]), 字符串中间对齐

ljust(width[, fillchar]), 字符串左对齐,不足部分用fillchar填充,默认的为空格

rjust(width[, fillchar]), 字符串右对齐,不足部分用fillchar填充,默认的为空格

zfill(width), 把字符串变成width长,并在右对齐,不足部分用0补足

expandtabs([tabsize])把字符串中的制表符(tab)转换为适当数量的空格。

fillchar 参数指定了用以填充的字符,默认为空格

zfill的z为zero的缩写,顾名思义,是以字符0进行填充,用于数值输出

expandtabs()的tabsize 参数默认为8。它的功能是把字符串中的制表符(tab)转换为适当数量的空格。

9、编码

encode([encoding[,errors]]),

decode([encoding[,errors]])

这是一对互逆操作的方法,用以编码和解码字符串。因为str是平台相关的,它使用的内码依赖于操作系统环境,

而unicode是平台无关的,是Python内部的字符串存储

Python嵌套函数和闭包

在Python语言中,可以在函数中定义函数。 这种在函数中嵌套定义的函数也叫内部函数。我们来看下面的代码:

上述代码中,定义了函数greet,在函数greet内部又定义了一个函数inner_func, 并调用该函数打印了一串字符。

我们可以看到,内部函数inner_func的定义和使用与普通函数基本相同。需要注意的是变量的作用域,在上述代码中,函数参数name对于全局函数greet是局部变量,对内部函数inner_func来说则是非局部变量。内部函数对于非局部变量的访问规则类似于标准的外部函数访问全局变量。

从这个例子我们还可以看到内部函数的一个作用,就是通过定义内部函数的方式将一些功能隐藏起来,防止外部直接调用。常见的场景是,在一个复杂逻辑的函数中,将一些小的任务定义成内部函数,然后由这个外层函数使用,这样可以使代码更为清晰,易于维护。这些内部函数只会在这个外层函数中使用,不能被其他函数或模块使用。

在Python语言中, 函数也是对象,它可以被创建、赋值给变量,或者作为函数的返回值。我们来看下面这个例子。

在上述代码中,在函数gen_greet内部定义了inner_func函数,并返回了一个inner_func函数对象。外部函数gen_greet返回了一个函数对象,所以像gen_greet这样的函数也叫工厂函数。

在内部函数inner_func中,使用了外部函数的传参greet_words(非局部变量),以及函数的参数name(局部变量),来打印一个字符串。

接下来,调用gen_greet("Hello")创建一个函数对象say_hello,紧接着调用say_hello("Mr. Zhang"),输出的结果为:Hello, Mr. Zhang!

同样的,调用gen_greet("Hi")创建一个函数对象say_hi,调用say_hello("Mr. Zhang"),输出的结果为:Hi,Tony!

我们可以发现,gen_greet返回的函数对象具有记忆功能,它能够把所需使用的非局部变量保存下来,用于后续被调用的时候使用。这种保存了非局部变量的函数对象被称作闭包(closure)。

那么闭包是如何实现的呢?其实并不复杂,函数对象中有一个属性__closure__,它就是在创建函数对象时用来保存这些非局部变量的。

__closure__属性是一个元组或者None类型。在上述代码中,我们可以通过下面方式查看:

函数的嵌套所实现的功能大都可以通过定义类的方式来实现,而且类是更加面向对象的代码编写方式。

嵌套函数的一个主要用途是实现函数的装饰器。我们看下面的代码:

在上述代码中,logger函数返回函数with_logging,with_logging则是打印了函数func的名称及传入的参数,然后调用func, 并将参数传递给func。其中的@wraps(func)语句用于复制函数func的名称、注释文档、参数列表等等,使得with_logging函数具有被装饰的函数func相同的属性。

代码中接下来用@logger对函数power_func进行修饰,它的作用等同于下面的代码:

可见,装饰器@符其实就是上述代码的精简写法。

通过了解了嵌套函数和闭包的工作原理,我们在使用过程中就能够更加得心应手了。


标题名称:包含python实现工厂函数的词条
新闻来源:http://cqcxhl.cn/article/hhhccc.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP