X Tutup
logging module: 相应组件 logger:提供了应用接口,供程序使用 handlers:用来将logger创建的log 发送到相应的目的地 filter:为要输出的日志提供了更细粒度的设置 formatters:设置最终的输出格式 logger objects pass along relevant log messages to all interested log handlers. logger can have more than one handler,so the application can send log messages to the different target,like,console,file,email and so on。for example,you normal log can send to timerotatingfile and you warning or error log can send mail to developer, so you can fix it in the first time。 A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: logger = logging.getLogger(__name__) you can create a log config file and read it use fileconfig() function API: http://python.jobbole.com/85279/ date & time module: arrow http://arrow.readthedocs.io/en/latest/ ------------------------------------------------------------------------------------------------------------------------- socket moudle socket.accept() Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection. so a python client-server program total have three socket object ,one in server, other in client, they all created in init,and the third one is connection,which returned by the server‘s socket accept method(like sock, addr = socket.accept(),so this sock is that connection) 注意,accept()针对客户端的connect()方法,相应的recv()针对send()方法 ------------------------------------------------------------------------------------------------ gevent moudle gevent是目前应用非常广泛的网络库,高效的轮询IO库libev加上greenlet实现的协程(coroutine) -------------------------------------------------------------------------------------------------- greenlet generator实现的协程在yield value时只能将value返回给调用者(caller)。 而在greenlet中,target.switch(value)可以切换到指定的协程(target), 然后yield value。greenlet用switch来表示协程的切换,从一个协程切换到另一个协程需要显式指定。 在switch之前,greenlet是知道你在switch之前做的是什么操作的,比如下列程序: from greenlet import greenlet def test1(x, y): z = gr2.switch(x + y) #here print("test1" , z) def test2(u): print("test2", u) gr1.switch({"kkk": 5, "ppp": 6, "mmm": 7},[1,2,3]) #here1 gr1 = greenlet(test1) gr2 = greenlet(test2) print(gr1.switch("hello", "world")) 输出: test2 helloworld test1 ({'ppp': 6, 'mmm': 7, 'kkk': 5}, [1, 2, 3]) #here2 None greenlet是知道你在here处,在switch到gr2之前是赋值操作的(也就是挂起前的程序,其实也就时所谓的上下文,也就是下文描述的二叉树的一个子树,假设为左树), 所以在here1处当switch到gr1时,虽然带了两个参数,一个字典,一个列表,但greenlet把它们合成了元组赋值给了z(此处因为here1处没有return,故回到here处 时继续向下执行了左树。如果有return就会在父节点退出,而不会有here2处的打印),故有here2处的打印输出内容。另外switch不是赋值,而是一个二叉树式的选择, 且换到了另一个棵子树。默认的子树parent取决于greenlet创建子树时的环境。如上列,左子树gr1,右子树gr2,属于parent “main greenlet” 使用greenlet需要注意以下三点: 第一:greenlet创生之后,一定要结束,不能switch出去就不回来了,否则容易造成内存泄露。 第二:python中每个线程都有自己的main greenlet及其对应的sub-greenlet ,不能线程之间的greenlet是不能相互切换的。(协程基于线程) 第三:不能存在循环引用,这个是官方文档明确说明。 对于异步非阻塞,而且还需要保留上下文的场景,greenlet也就时协程非常适用。greenlet很强大,可以从一个协程切换到任意其他协程,这是generator做不到的, 但这种能力其实也是双刃剑,前面的注意事项也提到了,必须保证greenlet的正常结束,在协程之间任意的切换很容易出问题。比如对于服务之间异步请求的例子, 简化为服务A的一个函数foo需要异步访问服务B,可以这样封装greenlet:用decorator装饰函数foo,当调用这个foo的时候建立一个greenlet实例, 并为这个greenlet对应一个唯一的gid,在foo方法发出异步请求(写到gid)之后,switch到parent,这个时候这个新的协程处于挂起状态。当请求返回之后, 通过gid找到之前被挂起的协程,恢复该协程即可。More simple More safety,保证旨在main和一级子协程之间切换。需要注意的是处理各种异常 以及请求超时的情况 ,避免内存泄露,gevent对greenlet的使用大致也是这样的。 可以继承greenlet.greenlet,子类需要实现run方法,当调用greenlet.switch方法时会调用到这个run方法 --------------------------------------------------------------------------------------------------------- data visuali moudle seaborn matplotlib plotly data analysis moudle scipy statsmodels TA-Lib(https://zhuanlan.zhihu.com/p/20613026)
X Tutup