Skip to content

Instantly share code, notes, and snippets.

@BruceChen7
Last active August 4, 2020 03:44
Show Gist options
  • Save BruceChen7/10952947 to your computer and use it in GitHub Desktop.
Save BruceChen7/10952947 to your computer and use it in GitHub Desktop.
[#python#try#logging#dict#module#set#list] #python #try#logging#dict#set#list

资料来源

python3 import

项目组织

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

set

## 生成式
{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]

itertools操作

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)]  

logging

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)
    

不要在模块级别使用logger

# 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

来启动程序

collections

## 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)

打印requests_oauthlib库调试日志

log = logging.getLogger('requests_oauthlib')                                                        
log.addHandler(logging.StreamHandler(sys.stdout))                                                   
log.setLevel(logging.DEBUG) 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment