@spiritnotes
2016-08-21T12:15:44.000000Z
字数 4087
阅读 1662
Python
读书笔记
顶层 | 1 | 2 | 3 |
---|---|---|---|
foobar(dir) | |||
docs(dir) | |||
conf.py | |||
quickstart.py | |||
index.rst | |||
foobar(dir) | |||
__init__.py | |||
cli.py | |||
tests(dir) | |||
__init__.py | |||
test_cli.py | |||
setup.py | |||
README.RST | |||
requirements.txt | |||
test-requirements.txt | |||
etc(dir) | |||
tools(dir) | |||
bin(dir) | |||
data(dir) |
- 版本编号 pep440
- 编码风格与自动检查
- pep8
- pyflakes
- pylint
- flake8
- hacking
测试应该保存在应用程序或库的tests子模块中。可以使测试代码随模块一同分发。一般采用模块树的层次结构作为测试树的层级结构。
fixtures模块提供了一些内置的fixtures(EnvironmentVariable),也提哦哪个一种简单的创建类和对象的机制(useFixture)
mock对象即模拟对象,用来通过某种特殊和可控的方式模拟真实应用程序对象的行为。在创建精确地描述测试代码的状态的环境时,非常有用。
Python2中为mock,Python3中为unit.mock
try:
from unittest import mock
except ImportError:
import mock
Mock基本用法
m = mock.Mock()
m.some_method.return_value = 42
m.some_method.side_effect = f
m.some_method.call_count
m.some_method.assert_called_once_with(... ) # mock.Any 匹配任何参数
补丁函数
with mock.patch('a.b.f', g):
a.b.f() # 调用g
使用装饰器版本
def get_f(code, content):
m = mock.Mock()
m.status_code = code
m.content = content
def f_g(url):
return m
return f_g
class X(unittest.TestCase):
@mock.patch('request.get', get_f(200, 'fd'):
def test_python_is(self):
self.assertTrue(...)
装饰器本质上就是一个函数,这个函数接受其他函数作为参数,并且以一个新的修改后的函数进行替换
def identity(f):
return f
_functions = {}
def register(f):
global _functions
_funcitons[f.__name__] = f
return f
新函数缺少原函数的属性,如docstring和名字,使用functools.wraps
def decsrop(f):
@functools.wraps(f)
def wrap(*args, **kwargs):
...
f(*args, **kwargs)
...
return wrap
要找特定的函数参数不够智能,使用inspect模块
def desc.(f):
def wraps(*args, **keargs):
func_args = inspect.getcallargs(f, *arg, **kwargs)
if func_args.get('user_name') != 'admin':
raise ...
f(*args, **kwargs)
...
return wraps
方法是作为类属性保存的函数。
Python3将未绑定方法去掉,而默认作为多一个参数的调用,这样更加灵活,使得该方法处理传入该类的实例外,还可以传入其他任何对象,只要该对象包含方法期望的属性。
采用实例引用方法时,python自动将类的方法绑定到实例。
m = Piz(42).get_size
m.__self__
m = m.__self__.get_szie
m()
静态方法属于类的方法,但实际上并非运行在类的实例上。
P.static_method is P().static_method is P(x).static_method
class A:
@staticmethod
def f():
print(1)
def g(self):
self.f() # 如果f为全局函数,则g在子类必须修改
class B(A):
@staticmethod
def f():
print(2)
b = B()
b.g()
类方法是直接绑定到类而非它的实例的方法。
A.cls_method is A(1).cls_nethod is A(2).cls_method
class A:
@classmethod
def from_z(cls, z):
return cls(z)
class B(A):
pass
b = B.from_z(1) # isinstance(b, B)
使用Python内置的abc模块
class A:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def f(self):
pass
class A(metaclass=abc.ABCMeta):
...
class A:
@classmethod
@abc.abstractmethod
def f(cls):
pass
Mixin(混入)类是指继承自两个或两个以上的类,并将它们的特性组合在一起。
Python中类也是对象,构建类的特定声明
class classname(expression or inheritance):
...
class A((lambda: object)()):
pass
class A(object):
pass
print A.mro()
super(B, B()).__init__
super(B).__self__ # 单类调用,返回未绑定的super对象
super(B, B()).__self__
如果是未绑定的super对象,则不能通过它访问类属性,因为其实例未定
- super类实现了描述符协议(__get__)
class D(C):
sup = super(C)
D().sup
D().sup.foo
在以函数式风格写代码时,函数应该设计成没有其他副作用。函数接受参数生成输出而不保留任何状态或修改任何不反映在返回值中的内容。
函数式变成特点:
生成器就是对象,每次调用它的next方法时返回一个值,直到它抛出StopIteration。
包含yield语句的Python函数。Python会将其标识为生成器。可以使用inspect对其进行检查。
inspect.isgeneratorfunction(mygenerator)
inspect.getgeneratorstate(mygenerator) #python3 only
range在python2中是返回列表,Python3中是生成器。
可以通过send对生成器传输值。
可以在单行内构造列表内容。可以使用多个for以及if判断进行过滤,原则上是不限制个数的。
Python2.7之后可以在单行构造字典和集合。
next(filter(lambda x:x>0, [-1, 0, 1, ...]))
first([-1,0,1], key=partial(operator.le, 0))