project/
main.py
sub1/
__init__.py
helper.py
sub2/
__init__.py
utils.py
tests/
__init__.py
test_sub1.py
test_sub2.py
运行一个测试例子
python -m tests.test_sub1
注意不是tests/test_sub1
running a single test case or test method. Also you can run a single TestCase or a single test method:
$ python -m tests.test_sub1.SampleTestCase
$ python -m tests.test_sub1.SampleTestCase.test_method
Running all tests One way is to use unittest discovery mentioned in the A Typical directory structure for running tests using unittest, as copied below:
$ cd new_project
$ python -m unittest discover
This will run all the test*.py modules inside the tests package.
# test for hex function
num = 16
print (hex(num)) # 0x10 convert a integer num to hex number;
num = '1'
print(int(num)) # convert a string or float num into int number
print(float(num))# convert a string or int num into float number
# test 2 for global num and id() function
num = 20
def fun():
num = 100
print id(num) #the num object in this function is different from the num outside the function,so the address is different
print num
fun()
print num # 20
print id(num) #id function return the address of the object
# test 3 for global num
def global_num():
global num # declare using a global num
num = 10
print num
print id(num)
num = 100
global_num()
print id(num) # two address is the same
print num
# test 4 use of len function
name = ['bruce','Li','Chen']
name1 = ('bruce',)
name2 = {'bruce':80,'Chen':100}
print len(name)# return the length of the name list
print len(name1)
print len(name)
# test 5 use of locals function
def locals_test():
num = 1;
num2 = 2
print locals()
print len(locals())
locals_test() # return {'num':1,'num2':2} <2></2>
# test 6 use of list function
# the same with tuple function
tmp = ['hello','world',1]
copy_tmp = list(tmp)
print copy_tmp #['hello', 'world', 1]
copy_tmp = list()
print copy_tmp #[]
# test 7 use of raw_input function
s = raw_input('--> ') #--> write to the standard output
print s; #if you input 'Hello world',then output 'hello world'
# use of open function and try...except
try:
f = open('a.txt','r') # return a file openjec
except IOError:
print 'can\'t find the file'
else:
print 'Other errors happen'
# test 8 use of dir function return the list of names in the current local scope.
class Teacher:
def __init__(self,name,age):
self.name = name
self.age = age
instance = Teacher('bruce',12)
print dir(instance) #['__doc__', '__init__', '__module__', 'age', 'name']
# use of max function
fruit = ['apple','banala','juice']
num = [1,2,3]
print max(num)
print max(fruit)
# use of type function
fruit = "apple"
num = 1
print type(fruit) #<type 'str'>
print type(num) #<type 'int
def TryExcept():
try:
...
except Exception as e:
print e
os.environ["HOME"] # 主目录
os.path.exist(file_name) #文件是否存
';'.join(['1', '2', '3'])
# '1;2;3'
# cat test.txt
# 111
# 222
# 333
f=open('test.txt', 'r')
';'.join(f)
# '111\n;222\n;333\n' #文件内容的join
# 关键字格式化
"hello %(name)s" % {'name': 'word', 'key2': 'val2'}
# 'hello word'
"hello {name}".format(**{'name': 'word'})
# 行分隔
'Line 1\n\nLine 3\rLine 4\r\n'.splitlines()
# ['Line 1', '', 'Line 3', 'Line 4']
# 字符分隔
'1,2,3'.split(',', 1)
# ['1', '2,3']
'1,2,3'.rsplit(',', 1)
# ['1,2', '3']
## 重复多次
[1, 2, 3] * 2
# [1, 2, 3, 1, 2, 3]
for i, v in enumerate(['a', 'b', 'c']):
print i, v
# 0 a
# 1 b
# 2 c
# 第二个参数, 可指定开始迭代的索引起始值
for i, v in enumerate(['a', 'b', 'c'], 1):
print i, v
# 1 a
# 2 b
# 3 c
## 查找
# 返回 templates 列表中,template_id字段为 2 的元素(字典)
(item for item in templates if item["template_id"] == 2).next()
# 上面语句在找不到对应元素时会抛出StopIteration异常,如果不希望抛异常
# 可以使用next()内置函数指定默认值
next((item for item in templates if item["template_id"] == 2), None)
# 找不到时,返回None
## 生成式
{i for i in [1, 2, 2, 3]}
#实际上{1,2,3} 相当于 set([1,2,3])
a = {1, 2, 3}
a.remove(4) # 4 不在set 抛 KeyError异常
a.discard(4) # 不会抛出异常
# 添加集合项
s = {3, 4, 5}
s.update([1,2,3])
print s
# set([1, 2, 3, 4, 5])
s <= r # 相当于s.issubset(r) s 是否为r的子集
s >= r # 相当于s.issuperset(r) s是否为r的超集
s < r #s 是否为r的真子集
s > r #s 是否为r的真超集
s | r # 相当于s.union(r) 返回s和r的并集
s & t # 相当于s.intersection(t)返回s和r的交集
s - t # 相当于s.difference(t)返回s和t的差集(s有但是t没有的元素)
s ^ t # 相当于s.symmetric_difference(t) 返回个新集合,是s或t的成员,但不是s和t共有的成员
d = {'a': 1}
d.update({'b': 2, 'c': 3})
# 更好看的写法
d.update(b=2, c=3)
## 默认设置字典的值,没有则改变,否则不改变
d = {'a': 1, 'b': 2}
d.setdefault('a', 2)
d.setdefault('c', 3)
print d
{'a': 1, 'c': 3, 'b': 2}
# defaultdict
strings = ('a', 'b', 'c', 'a','d', 'c', 'c', 'a')
# 如果counts的key不存在,则给定一个默认值0
counts = defaultdict(int)
# 词频统计
for kw in strings:
counts[kw] += 1
## python的字典是无序的, OrderedDict可以保留key的顺序信息
## OrderedDict的Key会按照插入的顺序排列
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od.keys()
# 按照插入的Key的顺序返回
# ['z', 'y', 'x']
创建一个字典,和给字典赋值都是比较简单的,按照下面,即可创建。
>>> dict1 = {}
>>> dict2 = {'name': 'earth','port': 80}
当然,我们也可以使用工厂方法来创建
>>> fdict = dict((['x',1],['y',2]))
>>> fdict
{'y':2,'x':1}
>>> fdict = dict(name= "hello",sex ="male")
{"name":"hello","sex":"male"}
要遍历一个字典,使用in
操作,然后通过字典键加上括号来访问其值
>>> dict2 = {'name': 'earth','port': 80}
>>> for key in dict2
>>> print 'key= %s,value = %s' %(key,dict2[key])
如果访问一个不存在的键将会报错。
可以有几种方式对一个字典做修改:添加一个数据项或者是新元素,修改一个已经存在的数据项,删除一个已经存在的数据项。
>>>dict2['name'] = 'venus'
>>>dict2['port'] = 6969
如果字典中该键已经存在,则字典中该键对应的值将被新值替代.
通常删除整个字典的操作是不常见的,下面记录了删除的代码:
del dict2['name']#删除name的条目
dict2.clear() #删除整个条目
在python字典中输入:dict.xxx
。
- len(dict)获取字典项目
- clear() 清除所有的项
- copy() 浅拷贝复制
- fromkeys(seq,[,value]) 创建一个新的字典,键来自seq,值设置为value。
- get(key[,default])获取某个键的值,如果没有该键,默认返回None,当然你可以改变默认值
- items()将所有的字典项以列表的方式返回,其中每一项都是来自于键和值。(这个键和值共同组成元祖)但在返回的时候, 没有特殊顺序。
- iteritems()的作用相同,但是返回的是迭代器对象而不是列表。
- keys() 将字典中的键以列表的方式返回。
- pop(key[,default]) 如果键值存在,那么直接删除该键-值对,并且返回其值,如果default没有给,并且键不存在,那么会产生KeyError
## 生成式
a = [1, 2, 3, 4, 5, 6]
['%02d' %i for i in a]
# ['01', '02', '03', '04', '05', '06']
# 区别if的位置
[ expression for item in list if conditional ]
[ val1 if conditional else val2 for item in list]
# 上面其实是python的类三目运算符例子
[ i for i in [1, 2, 3] if i >= 3] [3]
## 多层嵌套
l = [[1,3],[5,7,6]]
[item for sublist in l for item in sublist]
# [1, 3, 5, 7, 6]
[item for sublist in l for item in sublist if item >3]
# [5, 7, 6]
# 列表倒序
a[::-1]
import itertools
x = itertools.accumulate(range(10)) # 对range迭代器进行累加
print(list(x)) # [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
# 连接多个迭代器
x = itertools.chain(range(3), range(4), [3,2,1])
print(list(x)) # [0, 1, 2, 0, 1, 2, 3, 3, 2, 1]
# 求列表或生成器中指定数目的元素不重复的所有组合
x = itertools.combinations(range(4), 3)
print(list(x)) # [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
# 按照真值表筛选元素
x = itertools.compress(range(5), (True, False, True, True, False))
print(list(x)) # [0, 2, 3]
# 保留对应真值为False的元素
x = itertools.filterfalse(lambda e: e < 5, (1, 5, 3, 6, 9, 4))
print(list(x)) # [5, 6, 9]
# 按照分组函数的值对元素进行分组
x = itertools.groupby(range(10), lambda x: x < 5 or x > 8)
for condition, numbers in x:
print(condition, list(numbers)) # True [0, 1, 2, 3, 4] False [5, 6, 7, 8] True [9]
# 产生指定数目的元素的所有排列(顺序有关)
x = itertools.permutations(range(4), 3)
print(list(x))
#
x = itertools.repeat(0, 5)
print(list(x)) #[0, 0, 0, 0, 0]
# 按照真值函数丢弃掉列表和迭代器前面的元素
x = itertools.dropwhile(lambda e: e < 5, range(10))
print(list(x)) # [5, 6, 7, 8, 9]
# 与dropwhile相反,保留元素直至真值函数值为假。
x = itertools.takewhile(lambda e: e < 5, range(10))
print(list(x)) # [0, 1, 2, 3, 4]
#
x = itertools.zip_longest(range(3), range(5))
y = zip(range(3), range(5))
print(list(x)) #[(0, 0), (1, 1), (2, 2), (None, 3), (None, 4)]
print(list(y)) #[(0, 0), (1, 1), (2, 2)]
- 资料:https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python
- https://www.cnblogs.com/yyds/p/6901864.html
- https://www.jianshu.com/p/feb86c06c4f4
import logging
from logging import NullHandler
logging.basicConfig(level=logging.DEBUG) #默认是WARNING
logger = logging.getLogger(__name__)
logger.addHandler(NullHandler()) #日志默认写到终端
# 添加一个handler来讲日志写到文件中
# create a file handler
handler = logging.FileHandler('hello.log')
handler.setLevel(logging.INFO)
# create a logging format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(handler)
logger.debug('%s iteration, item=%s', i, item)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
## 打印异常信息
try:
open('/path/to/does/not/exist', 'rb')
except (SystemExit, KeyboardInterrupt):
raise
except Exception, e:
logger.error('Failed to open file', exc_info=True) #使用exec_info=True,来把异常打印出来
# 等价于logger.exception(msg, *args)
# my_module.py
import logging
logger = logging.getLogger(__name__)
def foo():
logger.info('Hi, foo')
class Bar(object):
def bar(self):
logger.info('Hi, bar')
# main.py
import logging
# load my module
import my_module
# load the logging configuration
logging.config.fileConfig('logging.ini')
my_module.foo()
bar = my_module.Bar()
bar.bar()
logging.ini
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
在这个例子中,在模块级别中使用了logging,而在main.py中,你什么日志都不能打印。为什么??
Because you create the logger at module level, you then import the module before you load the logging configuration from a file. The logging.fileConfig and logging.dictConfig disables existing loggers by default.
我们在my_module.py中,不放在module级别中.
import logging
def foo():
logger = logging.getLogger(__name__)
logger.info('Hi, foo')
class Bar(object):
def __init__(self, logger=None):
self.logger = logger or logging.getLogger(__name__)
def bar(self):
self.logger.info('Hi, bar')
或者是使用配置
import logging
import logging.config
logger = logging.getLogger(__name__)
# load config from file
# logging.config.fileConfig('logging.ini', disable_existing_loggers=False)
# or, for dictConfig
logging.config.dictConfig({
'version': 1,
'disable_existing_loggers': False, # this fixes the problem
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default': {
'level':'INFO',
'class':'logging.StreamHandler',
},
},
'loggers': {
'': {
'handlers': ['default'],
'level': 'INFO',
'propagate': True
}
}
})
logger.info('It works!')
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"simple": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"info_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "INFO",
"formatter": "simple",
"filename": "info.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
},
"error_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "ERROR",
"formatter": "simple",
"filename": "errors.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
}
},
"loggers": {
"my_module": {
"level": "ERROR",
"handlers": ["console"],
"propagate": false
}
},
"root": {
"level": "INFO",
"handlers": ["console", "info_file_handler", "error_file_handler"]
}
}
这样初始化logging
import os
import json
import logging.config
def setup_logging(
default_path='logging.json',
default_level=logging.INFO,
env_key='LOG_CFG'
):
"""Setup logging configuration
"""
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'rt') as f:
config = json.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
我们可以使用:
LOG_CFG=my_logging.json python my_server.py
来启动程序
## dequed的的使用使用
from collections import deque
# ctor which use iterable data
d = deque((1, 2, 3))
d1 = deque([1, 2, 3])
d2 = deque(range(10))
# append data to the end of deque
d.append(4) # 1, 2, 3, 4
d.appendleft(0) # 0, 1, 2, 3, 4
# count the number of deque number which equals 4
d.count(4) # 1
d.pop() # remove and return the right side of the deque
p.popleft() # remove and return the element of left side
# extend the right side of the deque
d.extend(iterable)
log = logging.getLogger('requests_oauthlib')
log.addHandler(logging.StreamHandler(sys.stdout))
log.setLevel(logging.DEBUG)