本文共 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/