Python
2013-12-23
collections.namedtuple
是一个工厂方法,用来创建一个 tuple 子类。
# python2
collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
# verbose = True 对于 Python 初学者来说非常好,创建类型时,会输出类的完整定义,用来学习 Python 类的一些特性。
# 这个参数在 python3.7 版被移除
# python3
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
from collections import namedtuple
DBConn = namedtuple('MySQL', ('host', 'port', 'username', 'password', 'db'))
conn = DBConn('localhost', '3306', 'root', '123456', 'test')
conn
# MySQL(host='localhost', port='3306', username='root', password='123456', db='test')
conn._asdict() # python2 输出 OrderedDict 类型
# {'host': 'localhost',
# 'port': '3306',
# 'username': 'root',
# 'password': '123456',
# 'db': 'test'}
conn.__class__
# __main__.MySQL
conn.host
# 'localhost'
Python 加密
2013-12-18
刚刚读了一遍 Discuz 系列产品中广泛使用的加密解密算法 authcode,受益匪浅,真是设计巧妙。
为了真的理解其中的想法,用 Python 改写了一遍。
Python
2013-11-30
一共四种风格,printf(百分号),format 方法,模板,fstring。
Python Tornado
2013-10-13
Tornado web server 是使用 Python 编写出來的一个极轻量级、高可伸缩性和非阻塞 IO 的 Web 服务器软件,著名的 Friendfeed 网站就是使用它搭建的。
Tornado 跟其他主流的 Web 服务器框架(主要是 Python 框架)不同是采用 epoll 非阻塞 IO,响应快速,可处理数千并发连接,特别适用用于实时的 Web 服务。
要使用它,必须按照以下套件:
1)Python(建议使用 Python 2.5 / Python 2.6)
2)Simplejson(建议使用 simplejson 2.0.9)
3)cURL(建议使用 curl 7.19.7 或以上版本)
4)Pycurl(建议使用 pycurl 7.16.2.1)
5)Tornado Web Server(这才是主角,版本就照官網上最新的安裝吧)
一个最简单的服务:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
在 Tornado 中运行 Django
#!/usr/bin/env python
# *-* encoding: utf-8 *-*
import os
import sys
import tornado.web
from tornado import autoreload
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.web import url
from django.conf import settings
from django.core.handlers.wsgi import WSGIHandler
if not os.path.dirname(__file__) in sys.path[:1]:
sys.path.insert(0, os.path.dirname(__file__))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
class Application(tornado.web.Application):
def __init__(self):
handlers = [
url(r"/static/(.+)", tornado.web.StaticFileHandler, dict(path=settings.MEDIA_ROOT), name='static_path'),
url(r"/media/(.+)", tornado.web.StaticFileHandler, dict(path=settings.MEDIA_ROOT), name='media_path'),
]
handlers.append(('.*', tornado.web.FallbackHandler, dict(fallback=WSGIContainer(WSGIHandler()))))
tornado.web.Application.__init__(self, handlers)
http_server = HTTPServer(Application())
http_server.listen(8080)
loop = IOLoop.instance()
autoreload.start(loop) #自动加载修改过的代码
loop.start()
Python Django
2013-09-23
运行 django runserver
的时候,出现 Error 10013,即 8000 端口被占用。
Python MySQLdb DB
2013-09-15
用 MySQLdb 操作数据库,插入数据之后发现数据库中依然为空,不知原因为何。
开启 mysqld 的 log 设置项之后发现日志文档中更有执行 sql 语句,直接复制语句在客户端中执行也没有问题,那么为什么通过 MySQLdb 的插入全部没有结果呢?
Python
2013-04-30
可迭代对象(Iterable)就是可以用 for 循环遍历的数据结构,包括字符串、元组、列表、字典、集合等内置类型,也可以通过一些方法来是实现自定义可迭代对象。
https://docs.python.org/3/glossary.html#term-iterable
https://docs.python.org/3/glossary.html#term-iterator
迭代协议与序列协议
- 迭代器协议(Iterator Protocol):如果一个对象包含
__next__
方法,那就是一个迭代器。
迭代器可以使用 next
函数连续获取数据,内部实现就是调用 __next__
方法获取一个数据项,如果循环结束,就会抛出 StopIteration
。
上面讲的是 CPython 实现,实际上 Python 语法规范要求迭代器一定要有 __iter__
方法。
一般实现中,都有加上 __iter__
方法,直接 return self
。
- 可迭代对象协议(Iterable Protocol):如果一个对象包含
__iter__
方法(返回一个迭代器对象),那么就是一个可迭代对象,
可以用在 for 循环,zip
,map
,filter
等需要可迭代对象的场景中。
-
序列对象协议(Sequence Protocol):如果一个对象包含 __getitem__
方法(使用 0 开始的整数作为索引),和 __len__
方法,
就可以执行一些序列对象的操作,比如...(?)。
字符串,元组,列表都是序列对象。set 无序,dict 是按 key 索引,所以都不是序列对象。
-
迭代器协议(Iterator Protocol):如果一个对象包含 __iter__
方法,和 __next__
方法,那就是一个迭代器。
迭代器可以使用 next
函数连续获取数据,内部实现就是调用 __next__
方法获取一个数据项,如果循环结束,就会抛出 StopIteration
。
CPython 没有按照语言规范要求迭代器一定要有 __iter__
方法。但一般实现中,都是加上 __iter__
方法,return self
。
- https://docs.python.org/3/c-api/abstract.html
- Iterator Protocol https://docs.python.org/3/c-api/iter.html
- Sequence Protocol https://docs.python.org/3/c-api/sequence.html
iter
iter(iterable)
iter(callable, sentinel) # sentinel:任意值都行
iter(1)
TypeError: 'int' object is not iterable
iter(1, 1)
TypeError: iter(v, w): v must be callable
iter 用于生成一个迭代器。
- for 循环遍历的时候,会通过 iter 方法创建一个迭代器。
- 可以创建迭代器的对象,必须支持 iterable protocol (包含
__iter__()
方法),
或者支持 sequence protocol (包含 __getitem__()
方法,使用 0 开始的整数作为索引)
原理
迭代器(Iterator)
迭代器是可迭代对象的一种。它是一个具有 __iter__()
和 __next__()
方法的对象,可以逐个返回可迭代对象的元素。
字符串、元组、列表、字典、集合这些内置类型就都不是迭代器。
PEP 234 – Iterators
https://peps.python.org/pep-0234/
自定义可迭代对象
class MyIterable:
def __init__(self, data):
self.data = data
def __iter__(self):
self.index = 0
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
a = MyIterable(['apple', 'banana', 'cherry'])
for item in a:
print(item)
Python
2013-04-17
示例
import string
import random
CHARS1 = string.ascii_letters
CHARS2 = string.ascii_letters + string.digits
def get_random_string(len=5, chars=None):
if not chars:
chars = CHARS1
return ''.join(random.choice(chars) for _ in range(len))
# python3
def get_random_bytes(len=5):
return bytes(bytearray((random.randrange(256) for _ in range(len))))
# python2
def get_random_bytes(len=5):
return ''.join(chr(random.randrange(256)) for _ in range(len))
其他 随机字节的方法:
import Cryptodome.Random
Cryptodome.Random.get_random_bytes(size)
In [15]: os.getrandom
Out[15]: <function posix.getrandom(size, flags=0)>
In [17]: os.urandom
Out[17]: <function posix.urandom(size, /)>
Python PythonNotes
2013-04-03
声明
a = set() # ps: {} 表示空字典
b = set([1, 2, 3])
c = {1, 2, 3}
方法清单
.add(x)
添加元素
.clear()
清空集合
-
.copy()
复制集合
-
.difference()
返回两个集合的差集
-
.difference_update()
在主集合中只移除交集部分
-
.discard()
删除集合中的元素
-
.intersection()
返回两个集合的交集
-
.intersection_update()
在主集合中只保留交集部分
-
.isdisjoint()
判断两个集合是否没有公共元素
.issubset()
判断一个集合是否是另一个集合的子集
.issuperset()
判断一个集合是否是另一个集合的超集
.pop()
删除并返回一个随机元素
-
.remove()
删除集合中的元素
-
.symmetric_difference()
返回两个集合的对称差集,即排除所有重复元素之后的合集
-
.symmetric_difference_update()
在主集合中加入其他集合中的元素,然后移除交集部分
-
.union()
返回两个集合的并集
.update()
在一个集合中添加另一个集合中的元素