本文共 16843 字,大约阅读时间需要 56 分钟。
王炳明的的学习笔记。

在同一行里,同时给两个变量赋同一值时,解释器知道这个对象已经生成,那么它就会引用大同一个对象。如果分成两行的话,解释器并不直达这个对象已经存在了,就会重新申请内存存放这个对象。

dist-packages是debian系的Linux系统(如Ubuntu)才有的目录,当使用apt去安装的Python包会使用dist-packages,而使用pip或者easy_install安装的包才会安装在site-packages下。
脚本或者项目的入口文件里的第一行 # ! / u s r / b i n / p y t h o n \#!/usr/bin/python #!/usr/bin/python,是执行Python进入console模式里的Python。
执行 e n v p y t h o n env python envpython时,会去 e n v ∣ g r e p P A T H env | grep PATH env∣grepPATH的路径里依次查找名为Python的可执行文件。找到一个就执行。

IDE环境和CMD环境下运行结果不相同


python3.6 -m pip install xxx
直接相加
itertools方法
itertools内置模块专门用于操作可迭代对象。使用itertools.chain()函数先将可迭代对象串联起来,组成一个更大的可迭代对象,然后再利用list将其转化为列表。
使用 ∗ * ∗解包
∗ * ∗可以解包列表,解包后再合并。
使用extend
使用列表推导式
使用heapq
heapq是Python的标准模块,提供了堆排序算法的实现,该模块里面的merge方法,可以用于合并多个列表。
heapq.merge得到的是一个始终有序的列表,因为它采用堆排序,效率非常高。
魔法方法
直接相加实际是作用在KaTeX parse error: Expected group after '_' at position 1: _̲_add__魔法上。
yield from方法
原地更新
字典对象内置方法update,用于把另一个字典更新到自己身上。
先解包再合并
借助itertools
借助ChainMap
使用ChainMap时,当字典间有重复的键值时,只会取第一个值,排在后面的键值并不会更新掉前面的。
使用dict.items()合并
字典解析式
使用in和not in
使用find方法
使用 字符串对象的find方法,如果有找到子串,就可以返回指定子串在字符串中的出现位置。如果没有找到,就返回-1。
使用index方法
字符串对象哟一个index方法,可以返回指定子串在该字符串中第一次出现的索引,如果没有找到会抛出异常,因此使用时需要注意捕获。
使用count方法
只要判断结果大于0就说明子串存在于字符串中。
通过魔法方法
借助operator
operator模块是Python内置的操作符函数接口,它定义了一些算术和比较内置操作的函数。operator模块是用c实现的,所以执行速度比Python代码快。在operator中有一个方法contains,可以很方便的判断子串是否在字符串中。
使用正则匹配
装饰器的使用方法很固定:
装饰器并不是编码必须的,它的出现,使代码:
def decorator(func): def wrapper(*args, **kw): return func() return wrapper@decoratordef function(): print('hello, decorator') #这是装饰器函数,参数function是被装饰的函数def logger(func): def wrapper(*args, **kw): print('开始执行:{}函数:'.format(func.__name__)) #真正执行的函数 func(*args, **kw) print('函数执行完了。') return wrapper@loggerdef add(x, y): print('{} + {} = {}'.format(x, y, x + y))add(20, 30) 
import time#装饰函数def timer(func): def wrapper(*args, **kw): t1 = time.time() #执行函数 func(*args, **kw) t2 = time.time() #计算时长 cost_time = t2 - t1 print('花费时间:{}'.format(cost_time)) return wrapper@timerdef want_sleep(sleep_time): time.sleep(sleep_time)want_sleep(10) 
def say_hello(country): def wrapper(func): def deco(*args, **kwargs): if country == 'china': print('你好!') elif country == 'america': print('hello.') else: return #真正习性函数的地方 func(*args, **kwargs) return deco return wrapper#小明,中国人@say_hello('china')def xiaoming(): pass#jack, 美国人@say_hello('america')def jack(): passxiaoming()print('-------')jack() 
class logger(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print('[INFO]: the function {func}() is running...'.format(func=self.func.__name__)) return self.func(*args, **kwargs)@loggerdef say(something): print('say {}!'.format(something))say('hello') 
class logger(object): def __init__(self, level='INFO'): self.level = level def __call__(self, func): def wrapper(*args, **kwargs): print('[{level}]: the function {func}() is running...'.format(level=self.level, func=func.__name__)) func(*args, **kwargs) return wrapper@logger(level='WARNING')def say(something): print('say {}!'.format(something))say('hello') 
import timeimport functoolsclass DelayFunc: def __init__(self, duration, func): self.duration = duration self.func = func def __call__(self, *args, **kwargs): print('Wait for {duration} seconds...'.format(duration=self.duration)) time.sleep(self.duration) return self.func(*args, **kwargs) def eager_call(self, *args, **kwargs): print('Call without delay') return self.func(*args, **kwargs)def delay(duration): """ 装饰器:推迟某个函数的执行 同时提供eager_call方法立即执行 """ #此处是为了避免定义额外函数 #直接使用functools.partial帮助构造DelayFunction实例 return functools.partial(DelayFunc, duration)@delay(duration=2)def add(a, b): return a + b 
一个实现了描述符协议的类就是一个描述符。在类里实现了__get__()、set()、delete()其中至少一个方法。实现保护属性不受修改、属性类型检查的功能,提高代码的复用率。
class Student: def __init__(self, name, math, chinese, english): self.name = name self.math = math self.chinese = chinese self.english = english @property def math(self): return self._math @math.setter def math(self, value): if 0 <= value <= 100: self._math = value else: raise ValueError('Valid value must be in [0, 100]') @property def chinese(self): return self._chinese @chinese.setter def chinese(self, value): if 0 <= value <= 100: self._chinese = value else: raise ValueError('Valid value must be in [0, 100]') @property def english(self): return self._english @english.setter def english(self, value): if 0 <= value <= 100: self._english = value else: raise ValueError('Valid value must be in [0, 100]') def __repr__(self): return ' '.format(self.name, self.math, self.chinese, self.english) 
数据描述符和非数据描述符的区别在于:他们相对实例的字典的优先级不同。
#数据描述符class DataDes: def __init__(self, default=0): self._score = default def __set__(self, instance, value): self._score = value def __get__(self, instance, owner): print('访问数据描述符里的__get__') return self._score #非数据描述符class NoDataDes: def __init__(self, default=0): self._score = default def __get__(self, instance, owner): print('访问非数据描述符里的__get__') return self._score class Student: math = DataDes(0) chinese = NoDataDes(0) def __init__(self, name, math, chinese): self.name = name self.math = math self.chinese = chinese def __getattribute__(self, item): print('调用__getattribute__') return super(Student, self).__getattribute__(item) def __repr__(self): return ' '.format(self.name, self.math, self.chinese) 
class Student: def __init__(self, name): self.name = name @property def math(self): return self._math @math.setter def math(self, value): if 0 <= value <= 100: self._math = value else: raise ValueError('Valid value must be in [0, 100]') class TestProperty(object): def __init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel self.__doc__ = doc def __get__(self, obj, objtype=None): print('in __get__') if obj is None: return self if self.fget is None: raise AttributeError return self.fget(obj) def __set__(self, obj, value): print('in __set__') if self.fset is None: raise AttributeError self.fset(obj, value) def __delete__(self, obj): print('in __delete__') if self.fdel is None: raise AttributeError self.fdel(obj) def getter(self, fget): print('in getter') return type(self)(fget, self.fset, self.fdel, self.__doc__) def setter(self, fset): print('in setter') return type(self)(self.fget, fset, self.fdel, self.__doc__) def deleter(self, fdel): print('in deleter') return type(self)(self.fget, self.fset, fdel, self.__doc__)class Student: def __init__(self, name): self.name = name #这里改变 @TestProperty def math(self): return self._math @math.setter def math(self, value): if 0 <= value <= 100: self._math = value else: raise ValueError('Valid value must be in [0, 100]') 等价的两种写法
![]()

class staticmethod: def __init__(self, f): self.f = f def __get__(self, obj, objtype=None): print('in staticmethod __get__') return self.fclass Test: def myfunc(): print('hello method2') #描述符的体现 myfunc = staticmethod(myfunc) #等价写法 class Test: @staticmethod def myfunc(): print('hello method1') 
class classmethod(object): def __init__(self, f): self.f = f def __get__(self, instance, owner=None): print('in classmethod __get__') def newfunc(*args): return self.f(owner, *args) return newfuncclass Test: def myfunc(cls): print('hello classmethod') myfunc = classmethod(myfunc) 
class Score: def __init__(self, default=0): self._value = default def __get__(self, instance, owner): return self._value def __set__(self, instance, value): if 0 <= value <= 100: self._value = value else: raise ValueErrorclass Student: math = Score(0) chinese = Score(0) english = Score(0) def __repr__(self): return ''.format(self.math, self.chinese, self.english)

class Score: def __init__(self, object): self.name = object def __get__(self, instance, owner): return instance.__dict__[self.name] def __set__(self, instance, value): if 0 <= value <= 100: instance.__dict__[self.name] = value else: raise ValueErrorclass Student: math = Score('math') chinese = Score('chinese') english = Score('english') def __init__(self, math, chinese, english): self.math = math self.chinese = chinese self.english = english def __repr__(self): return ' '.format(self.math, self.chinese, self.english) 
上下文管理器的优点:
with open('test.txt') as f: print(f.readlines()) 基本语法:
with EXPR as VAR: BLOCK
上下文表达式:with open(‘test.txt’) as f
上下文管理器:open(‘test.txt’) f不是上下文管理器,应该是资源对象。
在一个类里,实现了__enter__和__exit__的方法,这个类的实例就是一个上下文管理器。在编写代码的时候,可以将资源的连接或者资源获取放在__enter__中,将资源的关闭写在__exit__中。
class Resource(): def __enter__(self): print('===connect to resource===') return self def __exit__(self, exc_type, exc_val, exc_tb): print('===close resource connection===') def operate(self): print('===in operation===')with Resource() as res: res.operate() 
class Resource(): def __enter__(self): print('===connect to resource===') return self def __exit__(self, exc_type, exc_val, exc_tb): print('===close resource connection===') return True def operate(self): 1/0with Resource() as res: res.operate() 
在被装饰函数里,必须是一个生成器(带有yield),而yield之前的代码,就相当于__enter__里面的内容。yield之后的代码,就相当于__exit__里的内容。
import contextlib@contextlib.contextmanagerdef open_func(file_name): #__enter__ method print('open file:', file_name, 'in __enter__') file_handler = open(file_name, 'r') #important yield yield file_handler #__exit__ method print('close file:', file_name, 'in __exit__') file_handler.close() returnwith open_func('test.txt') as file_in: for line in file_in: print(line) 
import contextlib@contextlib.contextmanagerdef open_func(file_name): #__enter__ method print('open file:', file_name, 'in __enter__') file_handler = open(file_name, 'r') #important yield try: yield file_handler except Exception as exc: #deal with exception print('the exception was thrown') finally: print('close file:', file_name, 'in __exit__') file_handler.close() returnwith open_func('test.txt') as file_in: for line in file_in: 1/0 print(line) 
import contextlibimport shutil@contextlib.contextmanagerdef tempdir(**kwargs): argdict = kwargs.copy() if 'dir' not in argdict: argdict['dir'] = CONF.tempdir tmpdir = tempfile.makdtemp(**argdict) try: yield tmpdir finally: try: shuil.rmtree(tmpdir) except OSError as e: LOG.error(_LE('could not remove tempdir: %s'), e) import contextlib@contextlib.contextmanagerdef test_context(name): print('enter, my name is {}'.format(name)) yield print('exit, my name is {}'.format(name))with test_context('aa'): with test_context('bb'): print('=== in main ===') with test_context('aaa'), test_context('bbb'): print('=== in main ===') 
用itertools库实现for循环嵌套
list1 = range(1, 3)list2 = range(4, 6)list3 = range(7, 9)for item1 in list1: for item2 in list2: for item3 in list3: print(item1 + item2 + item3)
from itertools import productlist1 = range(1, 3)list2 = range(4, 6)list3 = range(7, 9)for item1, item2, item3 in product(list1, list2, list3): print(item1 + item2 + item3)

处理异常时,处理不当或者其他问题,再次抛出另一个异常,抛出的异常会携带元素的异常信息。
异常处理程序或finally块中引发异常,默认情况下,异常机制会隐式将先前的异常附加为新异常的__context__属性。这就是Python默认开启的自动关联异常上下文。try: print(1/0)except Exception as exc: raise RuntimeError('something bad happend') 
try: print(1/0)except Exception as exc: raise RuntimeError('something bad happend') from exc 
try: print(1/0)except Exception as exc: raise RuntimeError('bad thing').with_traceback(exc) 
try: print(1/0)except Exception as exc: raise RuntimeError('something bad happend') from None 
缓存是一种将定量数据加以保存,以备迎合后续获取需求的处理方式,加快数据获取的速度。
数据的生成过程可能需要经过计算、规整、远程获取等操作,如果是同一份数据需要多次使用,每次都重新生成会大大浪费时间。所以,如果将计算或者远程请求等操作获得的数据缓存下来,会加快后续的数据获取需求。
Python自带的缓存机制实现于functool模块中的lru_cache装饰器。
@functools.lru_cache(maxsize=None, typed=False)- maxsize:最多可以缓存多少个此函数的调用结果,如果为None,则无限制,设置为2的幂时,性能最佳。- typed:若为True,则不同参数类型的调用将分别缓存。
from functools import lru_cache@lru_cache(None)def add(x, y): print('calculating: %s + %s' % (x, y)) return x + yprint(add(1, 2))print(add(1, 2))print(add(2, 3)) 
使用with…open…可以从一个文件中读取数据,但是当使用read函数,Python会将文件的内容一次性的全部载入内存中,如果文件有10个G甚至更多,那么电脑就要消耗巨大的内存。如果用readline做一个生成器来逐行返回,但是如果文件内容就一行,还是会一次性读入全部内容到内存。最优雅的解决方法是,在使用read方法时,指定每次只读取固定大小的内容。
def read_from_file(filename, block_size=1024*8): with open(filename, 'r') as fp: with True: chunk = fp.read(block_size) if not chunk: break yield chunk
优化后:
from functools import partialdef read_from_file(filename, block_size=1024*8): with open(filename, 'r') as fp: for chunk in iter(partial(fp.read, block_size), ''): yield chunk
Python使用上下文管理器实现延时调用。
import contextlibdef callback(): print('B')with contextlib.ExitStack() as stack: stack.callback(callback) print('A') 
import timestart = time.time()#run the functionend = time.time()print(end - start)
import timeimport timeitdef run_sleep(second): print(second) time.sleep(second)print(timeit.timeit(lambda: run_sleep(2), number=5))

import sysimport contextliblog_file = 'test.log'def task(): pass@contextlib.contextmanagerdef close_stdout(): raw_stdout = sys.stdout file = open(log_file, 'a+') sys.stdout = file yield sys.stdout = raw_stdout file.close()with close_stdout(): task()
mstr = 'abcd'ml = [1, 2, 3, 4]mstr[::-1]ml[::-1]

def func(item, item_list=[]): item_list.append(item) print(item_list)func('iphone')func('xiaomi', item_list=['oppo','vivo'])func('huawei') 
转载地址:http://mpqs.baihongyu.com/