python知识点积累
内置函数map、zip、filter:
- map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
例:
a = [1,2,3]
b = map(lambda x:x*2,a)
print(list(b)) # [2, 4, 6]
- zip函数的原型为:zip([iterable, …])
参数iterable为可迭代的对象,并且可以有多个参数。该函数返回一个以元组为元素的列表,其中第 i 个元组包含每个参数序列的第 i 个元素。返回的列表长度被截断为最短的参数序列的长度。只有一个序列参数时,它返回一个1元组的列表。没有参数时,它返回一个空的列表。
例:
a = [1,2,3]
b = [1,2,3,4]
c = zip(a,b)
print(list(c)) # [(1, 1), (2, 2), (3, 3)]
如果这个不是你想要的效果,那么还可以使用 itertools.zip_longest() 函数来代替
from itertools import zip_longest
a = [1,2,3]
b = [1,2,3,4]
c = zip_longest(a,b,fillvalue=0) # fillvalue 按照指定内容填充,默认为None
print(list(c)) # [(1, 1), (2, 2), (3, 3), (0, 4)]
3.filter
def test(n):
return n%2 == 0
li = [1,2,3,4,5,6,7,8,9,10]
res = filter(test,li)
print(list(res))
偏函数:
functools.partial(固定的函数, args(值), *kw(键值对)),partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。
例:
from functools import partial
def test(a,b,c,d):
print(a,b,c,d)
s1 = partial(test,1)
s1(2,3,4) # 1 2 3 4
s2 = partial(test,d=11)
s2(1,2,3) # 1 2 3 11
s3 = partial(test,1,2,d=11)
s3(5) # 1 2 5 11
字典:
get方式
a[‘value’] 访问一个不存在的值报keyerror错误
a.get(‘value’) 访问一个不存在的值返回值为None
dic = dict()
print(dic.get("test")) # None
print(dic["test"])
# Traceback (most recent call last):
# File "C:\Users\Administrator\Desktop\test.py", line 3, in <module>
# print(dic["test"])
# KeyError: 'test'
有序字典
from collections import OrderedDict
d = OrderedDict([('first', 1),
('second', 2),
('third', 3)])
d.items()
#[('first', 1), ('second', 2), ('third', 3)]
默认创建空列表的字典
from collections import defaultdict
item = defaultdict(list)
sys.argv的意义及用法:
一个从程序外部获取参数的桥梁
例:
import sys
a=sys.argv[0] #>>> 11
print(a) # 11
exit函数:
调用exit()函数,终止Python程序。
json.load 和json.dump区别:
json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数
json.loads()用于将str类型的数据转成dict。
json.dump()用于将dict类型的数据转成str,并写入到json文件中。下面两种方法都可以将数据写入json文件
json.load()用于从json文件中读取数据。
property:
将方法变成属性
输出重定向:
import sys
s1 = ‘Hello,’
s2 = ‘world!’
sys.stdout = open(‘C:/Users/Administrator/Desktop/1.txt’,‘a’)
print(s1,s2)
print(s1,s2,end=’’)
print(s1,s2)
linux下的路径分割符
os.path.sep
encode 和decode区别:
decode的作用是将二进制数据解码成unicode编码,如str1.decode(‘utf-8’),表示将utf-8的编码字符串解码成unicode编码。
encode的作用是将unicode编码的字符串编码成二进制数据,如str2.encode(‘utf-8’),表示将unicode编码的字符串编码成utf-8。
正则表达式:
re.compile()函数可接受一个有用的标记–re.DOTALL。这使得正则表达式中的句点(.)可以匹配所有的字符,也包括换行符
Python正则表达式前的 r 表示原生字符串(rawstring):该字符串声明了引号中的内容表示该内容的原始含义,避免了多次转义造成的反斜杠困扰。
例:
正则表达式中使用“\”作为转义字符,如果需要匹配文本中的字符“\”,在正则表达式中需要4个“\”,首先,前2个“\”和后两个“\”在python解释器中分别转义成一个“\”,然后转义后的2个“\”在正则中被转义成一个“\”。
import re
# 不加r
content1 = '\\'
print(content1) # \
print(re.match('\\\\',content1)) #<re.Match object; span=(0, 1), match='\t'>
content2 = '\t'
print(content) # 空
print(re.match('\t',content)) #<re.Match object; span=(0, 1), match='\t'>
# 加r
content1 = r'\\'
print(content1) # \\
print(re.match(r'\\',content1)) #<re.Match object; span=(0, 1), match='\\'>
print(re.match(r'\\\\',content1)) #<re.Match object; span=(0, 1), match='\\\\'>
content2 = r'\t'
print(content) # \t
print(re.match(r'\\t',content)) #<re.Match object; span=(0, 1), match='\\t'>
csv文件换行处理:
添加 newline="",作不换行处理。
import csv
headers = ['Symbol','Price','Date','Time','Change','Volume']
rows = [('AA', 39.48, '6/11/2007', '9:36am', -0.18, 181800),
('AIG', 71.38, '6/11/2007', '9:36am', -0.15, 195500),
('AXP', 62.58, '6/11/2007', '9:36am', -0.46, 935000),
]
# 添加 newline="",不换行处理
with open('2.csv','w',newline='') as f:
f_csv = csv.writer(f)
f_csv.writerow(headers)
f_csv.writerows(rows)
只接受关键字参数的函数:
将强制关键字参数放到某个参数或者单个后面就能达到这种效果。
比如:
def recv(maxsize, *, block): # *后是关键字参数
pass
recv(1024, True) # TypeError
recv(1024, block=True) # Ok
> 摘自书籍:python3-cookbook
Python装饰器:
引用自博客作者:Refrain__WG
- 装饰器的作用: 在不改变原有功能代码的基础上,添加额外的功能,如用户验证等
- @wraps(view_func)的作用: 不改变使用装饰器原有函数的结构(如__name__, doc)
- 不使用wraps可能出现的ERROR: view_func…endpoint…map…
例:不加wraps
from functools import wraps
def my_decorator(func):
def wrapper(*args, **kwargs):
'''decorator'''
print('Calling decorated function...')
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""Docstring"""
print('Called example function')
print(example.__name__, example.__doc__) # wrapper decorator
> 摘自作者:hqzxsc2006
例:加wraps
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
'''decorator'''
print('Calling decorated function...')
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""Docstring"""
print('Called example function')
print(example.__name__, example.__doc__) # example Docstring
> 摘自作者:hqzxsc2006
多线程中阻塞(join)使用误区:
join( ) 阻塞主线程
join() 作用为阻塞主线程,即在子线程未返回的时候,主线程等待其返回然后再继续执行
join不能与start在循环里连用
以下为错误代码,代码创建了5个线程,然后用一个循环激活线程,激活之后令其阻塞主线程
threads = [Thread() for i in range(5)]
for thread in threads:
thread.start()
thread.join()
1
2
3
4
执行过程:
1. 第一次循环中,主线程通过start函数激活线程1,线程1进行计算
2. 由于start函数不阻塞主线程,在线程1进行运算的同时,主线程向下执行join函数
3. 执行join之后,主线程被线程1阻塞,在线程1返回结果之前,主线程无法执行下一轮循环
4. 线程1计算完成之后,解除对主线程的阻塞
5. 主线程进入下一轮循环,激活线程2并被其阻塞
如此往复,可以看出,本来应该并发的五个线程,在这里变成了顺序队列,效率和单线程无异
join的正确用法:使用两个循环分别处理start和join函数,即可实现并发
threads = [Thread() for i in range(5)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
> 摘自作者:brucewong0516
命名元组
from collections import namedtuple
test = namedtuple('test',['a','b','c'])
t = test(1,2,3)
print(t.a,t.b,t.c)
三目运算符
a=50
print(100) if a> 100 else print(200)
# 200
修改最大递归次数
import sys
sys.setrecursionlimit(3000)
闭包
- 函数中嵌套一个函数
- 外层函数返回内层函数的变量名
- 内层函数对外部作用域的一个非全局的变量进形引用
def func1():
a = 100
def func2():
b = a*2
print(b)
return func2
time装饰器
import time
def wrapper(func):
def count_time(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print('函数运行时间为:{:.5f}'.format(end_time - start_time))
return count_time
@wrapper
def t():
time.sleep(1)
print(1111)
t()
单例模式
class Test:
instance = None
def __new__(cls,*args,**kwargs):
if not cls.instance:
cls.instance = object.__new__(cls)
return cls.instance
else:
return cls.instance
单例模式装饰器
def single(func):
instance = {}
def fun(*args,**kwargs):
if func in instance:
return instance[func]
else:
instance[func] = func(*args,**kwargs)
return instance[func]
return fun
类实现装饰器
class Decorator:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
print("装饰器")
self.func()
魔法方法
str,repr
- 使用str函数或者print打印对象会优先触发str方法,没有定义str方法的情况下,会再去找repr方法,如果都没有,那么会去找父类的str方法。
- 使用repr方法或者交互环境下输入变量,会找自身的repr方法,自身没有repr方法,会再去找父类的repr方法
add
class Myadd():
def __init__(self,data):
self.data = data
def __str__(self):
return self.data
def __add__(self, other):
return self.data + other.data
s1 = Myadd('s1')
s2 = Myadd('s2')
print(s1) #s1
print(s2) #s2
print(s1+s2) #s1s2
dict
class Test():
__attr = 'hello'
print(Test.__dict__)
# {'__module__': '__main__', '_Test__attr': 'hello', '__dict__': <attribute '__dict__' of 'Test' objects>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None}
getattr,getattribute
class Test:
def __getattr__(self, item):
# 当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发
print('这是getattr')
super().__getattribute__(item)
def __getattribute__(self, item):
#当我们访问属性的时候,第一时间触发该方法去找属性
print('这是getattribute')
return super().__getattribute__(item)
b = Test()
b.name = 10
print(b.name1)
访问类的私有属性
class Test():
__attr = 'hello'
print(Test._Test__attr) # hello
限制对象属性
class Base:
# 指定类对象所能绑定的属性
__slots__ = ['name']
pass
b = Base()
b.name = 'test'
mysql上下文管理器
import pymysql
class DB:
# 数据库操作上下文管理器
def __init__(self,data_conf):
self.con = pymysql.connect(**data_conf)
self.cursor = self.con.cursor()
def __enter__(self):
return self.cursor
def __exit__(self, exc_type, exc_val, exc_tb):
self.cursor.close()
self.con.close()
DATBASES_CONF = dict(
host = "localhost",
user = "user",
password = "password",
database = "test",
port = 3306
)
with DB(DATBASES_CONF) as f:
f.execute('select * from test')
描述符
class Filed:
# 一个类中,只要出现以下三个方法的任何一个,那么该类就被称为描述器类
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = value
print(self) # <__main__.Filed object at 0x004E5040>
print(instance) # <__main__.Model object at 0x004C3D90>
print(value) # 10
def __delete__(self, instance):
print('del:',self) #del: <__main__.Filed object at 0x00675040>
class Model:
name = 'test'
attr = Filed()
m = Model()
m.attr = 10
print(m.attr) # 10
del m.attr
print(m) # <__main__.Model object at 0x00653E38>
正则表达式
import re
str = '<user@host.com>'
c= re.match("(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)",str)
print(c.group(0)) #<user@host.com>
print(c.group(1)) #<
元类
Test = type('Test',(object,),{"attr":100,"__attr2":200})
print(Test)
class Test1(object):
attr = 100
__attr2 = 200
print(Test1)
自定义元类
class MyMetaClass(type):
'''自定义元类'''
def __new__(cls,*args, **kwargs):
print(*args) #Test () {'__module__': '__main__', '__qualname__': 'Test', 'name': 'MuSen'}
print(**kwargs)
return super().__new__(cls,*args)
class Test(metaclass=MyMetaClass):
name = "MuSen"
print(Test().name)
改变环境变量
import sys
import os
curPath = os.path.abspath(os.path.dirname(__file__))
print(curPath)
rootPath = os.path.split(curPath)[0]
print(rootPath)
sys.path.append(rootPath)
pyinstaller
pyinstaller -F -i "1.jpg" demo.py
py2app
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['main.py']
DATA_FILES = []
OPTIONS = {
'argv_emulation': True,
'iconfile':'cool.icns',
'packages':['pandas','xlsxwriter']
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
py2applet --make-setup
python3 setup.py py2app --packages=pandas
允许的枚举成员和属性
class Mood(Enum):
FUNKY = 1
HAPPY = 3
def describe(self):
return self.name,self.value
def __str__(self):
return 'my custom str!{0}'.format(self.value)
@classmethod
def favorite_mood(cls):
return cls.HAPPY
#Mood.favorite_mood()
#<Mood.HAPPY: 3>
#Mood.HAPPY.describe()
#('HAPPY', 3)
#str(Mood.FUNKY)
#'my custom str! 1'
字符串类型unicode转码
.replace('%','\\').encode().decode('unicode-escape')