转自https://zhuanlan.zhihu.com/p/58623565

装饰器

装饰器实际上就是给其他函数和类附加额外功能 值得注意的是使用装饰器后代码的执行顺序
下面的例子,把foo函数传入的装饰器函数中去,装饰器函数返回一个可执行的wrapper函数,wrapper函数里面再执行foo函数

import logging

def use_logging(func):

    def wrapper(*args, **kwargs):
        logging.warn("%s is running" % func.__name__)
        return func(*args, **kwargs)   # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
    return wrapper

@use_logging    # 装饰器的逻辑是,把foo函数传入的装饰器函数中去,装饰器函数返回一个可执行的wrapper函数,wrapper函数里面再执行foo函数
def foo():
    print("i am foo")


foo()

生成器

生成器与列表推导有点类似,区别在于,列表推导一开始就执行完计算,返回的就是一个列表,而生成器返回的是一个生成器对象,里面保存的是生产数据的算法,可以步进的执行里面的逻辑。
list用的是[],generator是()

>>> L = [x * x for x in range(10)]   # 列表
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))  # 生成器对象
>>> g

也可以用yield将函数变为生成器:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
>>> f = fib(6)
>>> f
<generator object fib at 0x7fbea411ea20>

全都是对象

Python中所有的东西都是对象。包括整数、字符串、函数以及类。而且它们都是从元类type衍生而来

数据结构

python中的元组tuple一经定义就不可改变;
不过对于tuple中的引用类型数据(借用静态语言的概念),在不修改引用本身的情况下,是可以对这个引用内部的数据进行修改的 tuple中相当于保存的是指针,无需改变指针,就可以对指向的数据进行修改;

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

补码原码

python 存储负数的形式比较特殊,因为 python 的数字没有 32 / 64 位等概念,而高位的数字取决于此数字是正数还是负数,是正数则为 0 ,是负数则为 1
https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/