---函数注解----
In [1]: def clip(test:str,max_len:'int>0'=80) ->str:
...: pass
...:
参数注解:test:str,max_len:'int>0'
返回值注解:->str
In [2]: clip.__annotations__
Out[2]: {'test': str, 'max_len': 'int>0', 'return': str}
查看注解:__annotations__,其中return是返回值注解
----双下方法-----
__all__
all.py
__all__=['x','y','test']
x=2
y=3
z=4
def test():
print(‘test’)
test.py
from all import *
print(x)
print(y)
print(z)
test()
输出:
2
3
Traceback (most recent call last):
File "test.py", line 4, in <module>
print(z)
NameError: name 'z' is not defined
修改test.py:
from all import *
from all import z
print(x)
print(y)
print(z)
test()
输出:
2
3
4
test
__enter__和__exit__
实现了__enter__和__exit__方法,即支持上下文管理器协议。上下文管理器就是支持上下文管理器协议的对象,它是为了with而生。当with语句在开始运行时,会在上下文管理器对象上调用 __enter__ 方法。with语句运行结束后,会在上下文管理器对象上调用 __exit__ 方法
__repr__和__str__
__str__的功能与用法:
1.__str__功能:将实例对象按照自定义的格式用字符串的形式显示出来,提高可读性。
2.实例化的对象在打印或时会默认调用__str__方法,如果类没有重写这个方法,默认调用父类object的__str__方法。
3.object的__str__方法内部是pass,所以打印的是内存地址。如果当前类重写了这个方法,会自动调用重写后的方法。
__repr__的功能与用法
1.__repr__如果用IDE软件操作,功能与__str__完全一样,都是实例可视化显示
2.开发中如果用户需要可视化实例内容,只需要重写__str__或者__repr__方法之一即可。如果两个都有的话,默认调用__str__.
3.两者的区别就是使用命令行操作:
3.1__str__重写后,如果直接实例stu回车的话话,显示的是stu实例在内存中的地址,跟print(stu)不一样。
3.2__repr__重写后,如果直接实例stu回车的话,效果跟使用print(stu)一样,返回内容,不是内存地址。
__version__
In [19]: import urllib3
In [20]: urllib3.__version__
Out[20]: '1.25.8'
----装饰器------
· 闭包:
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
· 函数装饰器在导入模块时立即执行,而被装饰的函数只在明确调用时运行
· 装饰器原封不动地返回被装饰的函数,但是这种技术并非没有用处。很多 Python Web 框架使用这样的装饰器把函数添加到某种中央注册处,例如把URL模式映射到生成 HTTP 响应的函数上的注册处这种注册装饰器可能会也可能不会修改被装饰的函数
--property
class Student:
def __init__(self,name):
self.__name = name
@property #将函数变为对象的属性(只读)
def name(self):
return self.__name
@name.setter #修改name属性时,触发此函数
def name(self,new_name):
if type(new_name) is str:
self.__name = new_name
a1 = Student("Tom")
print(a1.name)
a1.name = 'jerry'
print(a1.name)
----高阶函数与列表推导式---
In [7]: def fact(num):return num*num
In [8]: map(fact,range(6))
Out[8]: <map at 0x7f1667778be0>
In [9]: list(map(fact,range(6))
...: )
Out[9]: [0, 1, 4, 9, 16, 25]
In [10]: [fact(n) for n in range(6)]
Out[10]: [0, 1, 4, 9, 16, 25]
In [14]: list(map(fact,filter(lambda n: n%2, range(6))))
Out[14]: [1, 9, 25]
In [15]: [fact(n) for n in range(6) if n%2]
Out[15]: [1, 9, 25]
----内置归约函数-----
sum 和 reduce 的通用思想是把某个操作连续应用到序列的元素上,累计之前的结果,把 一系列值归约成一个值。
all 和 any 也是内置的归约函数。
all(iterable)
如果 iterable 的每个元素都是真值,返回 True;all([]) 返回 True。
any(iterable)
只要 iterable 中有元素是真值,就返回 True;any([]) 返回 False
----内置函数---
--repr
>>>s = 'RUNOOB'
>>> repr(s)
"'RUNOOB'"
>>> dict = {'runoob': 'runoob.com', 'google': 'google.com'};
>>> repr(dict)
"{'google': 'google.com', 'runoob': 'runoob.com'}"
>>>
---isinstance
In [1]: ss='1111'
In [3]: isinstance(ss,str)
Out[3]: True
---防御可变参数---
错误示例:
In [22]: class Test:
...: def __init__(self,li=[]):
...: self.li=li
...:
#由于t1,t2都未传参,使用的默认li实际指向了同一个列表
In [23]: t1=Test()
In [24]: t2=Test()
In [27]: t1.li.append(1)
#t1的li中增加元素,会影响t2的li
In [28]: t2.li
Out[28]: [1]
正确示例:
In [29]: class Test:
...: def __init__(self,li=None):
...: if li:
...: self.li=li
...: else: #如果没有传参,每个实例都会创建一个新的空列表
...: self.li=[]
In [30]: t1=Test()
In [31]: t2=Test()
In [32]: t1.li.append([1,2,3,4])
In [33]: t2.li
Out[33]: []
----数据类型----
--字典:
字典排序:
#按value
kv_list = sorted(dic.items(),key=lambda x:x[1],reverse=True)
#按key
#kv_list = sorted(dic.items(),key=lambda x:x[0],reverse=True)
key_list = []
value_list = []
#遍历kv元组组成的list
for key,value in kv_list:
key_list.append(key)
value_list.append(value)
设置字典默认值:
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'
count = {}
for character in message:
count.setdefault(character, 0)
count[character] = count[character] + 1
print(count)
或:
count = {}
for char in message:
if char in count:
count['char']+=1
else:
count['char']=1
字典update()方法:
>>> dict = {'Name': 'Zara', 'Age': 7}
>>> dict2 = {'Sex': 'female' }
>>> dict.update(dict2)
>>> dict
{'Name': 'Zara', 'Age': 7, 'Sex': 'female'}
>>> dict3 = {'Age': 8 }
>>> dict.update(dict3)
>>> dict
{'Name': 'Zara', 'Age': 8, 'Sex': 'female'}
比较两个字典
>>> import operator
>>> operator.eq(dict2,dict3)
False
遍历时修改字典:
在字典遍历过程中修改字典元素,报错 RuntimeError: dictionary changed size during iteration,得知遍历时不能修改字典元素
解决办法:将遍历条件改为列表
for zone in list(dic.keys()):
if not dic[zone]:
del(dic[zone])
方法2,复制一个字典:
import copy
d = {'a': 1, 'b': 2, 'c': []}
for key, value in copy.deepcopy(d).items():
print(key, value)
if not value:
del d[key]
print(d)
修改字典key:
dict={'a':1, 'b':2}
dict["c"] = dict.pop("a")
--列表:
--append和extend
In [16]: ls = [1,2,3,4]
In [17]: ls.append([5,6,7,8])
In [18]: ls
Out[18]: [1, 2, 3, 4, [5, 6, 7, 8]]
In [21]: li = [1,2,3,4]
In [22]: li.extend([5,6,7,8])
In [23]: li
Out[23]: [1, 2, 3, 4, 5, 6, 7, 8]
--列表的深浅copy
浅copy:
li = [1,2,['aa','bb']]
li2 = li.copy()
li[0] = 'a'
li[2][0] = 'cc'
print(li,li2)
>>>>['a', 2, ['cc', 'bb']] [1, 2, ['cc', 'bb']]
深copy:
import copy
li = [1,2,['aa','bb']]
li3 = copy.deepcopy(li)
li[0] = 'a'
li[2][0] = 'cc'
print(li,li3)
--列表比较大小
#依次比较列表中的元素
In [8]: l1=[1,2,3]
In [9]: l2=[1,2,4]
In [10]: l3=[1,3,1]
In [11]: l1>l3
Out[11]: False
In [12]: l1<l2
Out[12]: True
#元素类型不相同会报错
In [13]: l4=[1,'2',5]
In [14]: l4>l1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-918a6d16635b> in <module>
----> 1 l4>l1
TypeError: '>' not supported between instances of 'str' and 'int'
#长度不一样的列表比较
In [15]: l5=[1,2,3,4]
In [18]: l5<l1
Out[18]: False
--迭代器:
取最后一个元素:
>>> *_,last =(i for i in range(1111111))
>>> last
1111110
或:
>>> for ls in (i for i in range(1111111)):
... continue
...
>>> print(ls)
1111110
分批读取:
#把0--1111放入长度100的列表
it = (i for i in range(1111))
start = 1
li = []
for i in it:
li.append(i)
start +=1
if start == 100:
print(li)
start = 1
li = []
#一定要有,不然最后一次循环没有处理
print(li)
给迭代器中元素加序号:
g = (i for i in range(33))
for i,v in enumerate(g,0):
print(i,v)
0 0
1 1
...
32 32