Python笔记
setproctitle
修改进程名用的
struct
和lua类似的字节流封装
头字符:表示字节顺序,大小和对齐方式
| 字符 | 字节顺序 | 大小 | 对齐方式 |
|---|---|---|---|
| @ | 按原字节 | 按原字节 | 按原字节 |
| = | 按原字节 | 标准 | 无 |
| < | 小端 | 标准 | 无 |
| > | 大端 | 标准 | 无 |
| ! | 网络(=大端) | 标准 | 无 |
格式字符
| 格式 | C 类型 | Python 类型 | 标准大小 | 注释 |
|---|---|---|---|---|
| x | 填充字节 | 无 | ||
| c | char | string of length 1 | 1 | |
| b | signed char | 整数 | 1 | (3) |
| B | unsigned char | 整数 | 1 | (3) |
| ? | _Bool | bool | 1 | (1) |
| h | short | 整数 | 2 | (3) |
| H | unsigned short | 整数 | 2 | (3) |
| i | int | 整数 | 4 | (3) |
| I | unsigned int | 整数 | 4 | (3) |
| l | long | 整数 | 4 | (3) |
| L | unsigned long | 整数 | 4 | (3) |
| q | long long | 整数 | 8 | (2), (3) |
| Q | unsigned long long | 整数 | 8 | (2), (3) |
| f | float | 浮点数 | 4 | (4) |
| d | double | 浮点数 | 8 | (4) |
| s | char[] | string | ||
| p | char[] | string | ||
| P | void * | 整数 | (5), (3) |
- '?' 转换码对应于 C99 定义的 _Bool 类型。 如果此类型不可用,则使用 char 来模拟。 在标准模式下,它总是以一个字节表示。
2.6 新版功能.
- 'q' 和 'Q' 只有在本地C编译器指出C long long类型行,或者在Windows上支持 __int64的时候才有效。在标准模式下一般都能用。
2.2 新版功能.
- 在使用任何整形转码的来包装非整形的时候,如果这个非整形有
__index__()方法,那么在包装之前会调用此方法来转换参数。 如果没有__index__()方法,或者调用__index__()发生了 TypeError 错误, 那么就会尝试__int__()。虽然__int__()已经废弃,且会抛出 DeprecationWarning。
在 2.7 版更改: 2.7中非整数据的
__index__()全新使用方法。
在 2.7 版更改: 在 2.7 版本中, 并不是所有的整形转换都使用
__int__()方法, DeprecationWarning 只会在 float 转换的时候抛出。
- 对于 'f' 和 'd' 格式字符, 封包形式用的是
IEEE 754 binary32 ('f')或者binary64 ('d')格式, 与平台使用的浮点格式无关。
- 'P' 格式字符仅对本机字节顺序可用(选择为默认或使用 '@' 字节顺序字符)。 字节顺序字符 '=' 选择使用基于主机系统的小端或大端排序。 struct 模块不会将其解读为本机排序,因此 'P' 格式将不可用。
格式字符之前可以带有整数重复计数。 例如,格式字符串 '4h' 的含义与 'hhhh' 完全相同。
格式之间的空白字符会被忽略;但是计数及其格式字符中不可有空白字符。
对于 '?' 格式字符,返回值为 True 或 False。 在打包时将会使用参数对象的逻辑值。 以本机或标准 bool 类型表示的 0 或 1 将被打包,任何非零值在解包时将为 True。
对于 's' 格式字符, 个数会解释为字符串的尺寸, 不想其他格式字符一样转换为重复次数; 例如, '10s' 表示的是一个简单的 10-字节字符串, 但是 '10c' 指的是 10 字符。如果没有指定个数的话,默认就是1。为了便于封包,字符串会被截断或者用空字节来填充来适配。对于解包,还是会根据指定的字节数完美的解出字符串。作为特里,'0s' 意味着一个单个的空的字符串(而 '0c' 代表 0 个字符).
对于'p' 格式字符对一个 “Pascal string” 编码, 意味着一个短的可变长度的字符串存储在一段指定长度的字节中。第一个字节存储的是字符串的长度,或者是255,无论如何都比255小。接下来的字节都是字符串的字节了。如果传入
pack()的字符串太长 (比count - 1还要长), 那么只会存储字符串前面的 count-1 字节。如果字符串比 count-1 , 那么会用空字节来填充,这样一来就可以用精确的字节数。注意,对于unpack(), 'p' 格式字符需要消费 count 字节,但是字符串永远都不要超过255个字符。
对于 'P' 格式字符,返回值是一个 Python 整形或者长整形,这取决于在转换为整形之后返回的指针的需要的大小。 NULL 指针永远是返回 Python 整数 0。在封包指针大小的值的时候, 会用到 Python 整形或者长整形。例如: Alpha 和 Merced 处理器使用的是 64-bit 指针值,意味着会用一个 Python 长整型来持有这个指针; 其他平台使用的是 32-bit 指针,那么他会用 Python 整形。
Tornado
WebSocket的使用方式
import tornado
import tornado.httpserver
import tornado.ioloop
app = tornado.web.Application([
(r"/", tornado.websocket.WebSocketHandlerExtended),
])
self._http_server = tornado.httpserver.HTTPServer(app)
self._http_server.bind(port) # websocket 端口
self._http_server.start(num_processes) #num_processes子进程数
tornado.ioloop.IOLoop.instance().start()
greenlet
轻量级协程,gevent 也是用的 greenlet
- 经常与线程 threads,或者Python内置的携程
async def配合使用 - 多线程有并发性的问题,需要用 queue 或者 locks 来避免 race condition,deadlock 以及其他的问题。greenlet之间是有序协作的,同时只能有一个greenlet运行。可以完全控制greenlet的切换,从而解决了竞态条件问题。
- 线程需要申请系统资源,如线程栈,系统预留,而 greenlet 只需要很少的资源
greenlet().switch()切换到这个调用 switch 的协程
Python 编码出错的问题
文件头里有
#!/usr/bin/env python
# -*- coding: utf-8 -*-
VS Code工具栏也显示的 UTF-8,那么看看控制台是否有乱码,有的话运行:chcp 65001 试试看
之前面试被问到过的MySQL引擎问题
collections库
# Counter
c = collections.Counter("hello world, hello world,hello world,hello ")
print c
# 查看元素
print list(c.elements())
# 获取元素的个数,也可以用get()
print c["h"]
c = collections.Counter("hello world hello world hello ".split())
print c
# c.update()
# defaultdict:指定value类型,不存在的给初始值
Counter({'l': 11, 'o': 7, ' ': 5, 'e': 4, 'h': 4, 'd': 3, ',': 3, 'r': 3, 'w': 3})
[' ', ' ', ' ', ' ', ' ', 'e', 'e', 'e', 'e', 'd', 'd', 'd', 'h', 'h', 'h', 'h', 'l', 'l', 'l', 'l', 'l', 'l', 'l', 'l', 'l', 'l', 'l', 'o', 'o', 'o', 'o', 'o', 'o', 'o', ',', ',', ',', 'r', 'r', 'r', 'w', 'w', 'w']
4
Counter({'hello': 3, 'world': 2})
d = collections.defaultdict(int)
d["a"] += 2
print d
s = [("a","b"),("b","c"),("a","c"),("a","d")]
d = collections.defaultdict(list)
for k,v in s:
d[k].append(v)
print d
defaultdict(<type 'int'>, {'a': 2})
defaultdict(<type 'list'>, {'a': ['b', 'c', 'd'], 'b': ['c']})
# OrderedDict:保留添加顺序
o = collections.OrderedDict()
o["1"] = 1
o["3"] = 3
o['2']=2
o["10"]=10
o["8"]=8
o["1"]=100 #重复赋值不会重新排序
print o
OrderedDict([('1', 100), ('3', 3), ('2', 2), ('10', 10), ('8', 8)])
# namedtuple(命名元组的构造器)
# 3种命名元组的方法
p = collections.namedtuple("Person",["age","height","name"])
print p
h = collections.namedtuple("Human","age, height, name")
Human1 = collections.namedtuple("Human1", "age height name")
tom = p(30, 178, "Tom")
print tom
print tom.age
<class 'main.Person'>
Person(age=30, height=178, name='Tom')
30
# deque 返回一个新的双向队列对象,支持线程安全,对于两端添加或者弹出,时间复杂度O(1)
# 虽然list对象也支持类似操作,但是这里优化了定长操作(pop(0)、insert(0,v))的开销
# 没指定maxLen,可以增长到任意长度,定长的如果满了会从另一端弹出
dq = collections.deque(maxlen=6)
print dq
dq.extend('python') # 从队列右侧添加iterable中的元素
print dq
dq.append("he") # 添加到右侧
print dq
dq.appendleft("ma") # 添加做左侧
print dq
deque([], maxlen=6)
deque(['p', 'y', 't', 'h', 'o', 'n'], maxlen=6)
deque(['y', 't', 'h', 'o', 'n', 'he'], maxlen=6)
deque(['ma', 'y', 't', 'h', 'o', 'n'], maxlen=6)
装饰器
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def a_new_decorator(a_func):
from functools import wraps
# 不加合格的话在外头打印func.__name__会打印到这里来
@wraps(a_func)
def warp_the_func():
print "Wrap Layer1 begin"
a_func()
print "Wrap Layer end"
return warp_the_func
def func_need_decotator():
print "Func Main"
func_need_decotator()
print "-----------------------------"
func_decotated = a_new_decorator(func_need_decotator)
func_decotated()
print "-----------------------------"
@a_new_decorator
def fun_with_decorator():
print "Hehe"
fun_with_decorator()
Func Main
Wrap Layer1 begin
Func Main
Wrap Layer endWrap Layer1 begin
Hehe
Wrap Layer end
Java注解
标记注解
//有点像定义一个接口一样,只不过它多了一个@
public @interface MyAnnotation {
}
元数据注解
普通使用
定义
public @interface MyAnnotation {
//定义了两个成员变量
String username();
int age();
}
使用
//注解拥有什么属性,在修饰的时候就要给出相对应的值
@MyAnnotation(username = "zhongfucheng", age = 20)
public void add(String username, int age) {
}
默认值
定义
public @interface MyAnnotation {
//定义了两个成员变量
String username() default "zicheng";
int age() default 23;
}
使用
@MyAnnotation()
public void add(String username, int age) {
}
注解为Value
定义
public @interface MyAnnotation2 {
String value();
}
使用
@MyAnnotation2("zhongfucheng")
public void find(String id) {
}
- 来源: 注解就这么简单

浙公网安备 33010602011771号