目录
一、迭代器generator与列表list
- generator
gen = (i for i in range(5))
print(2 in gen) # True
print(1 in gen) # False
迭代器迭代到元素后,之前的元素会丢弃。
- list/tuple
gen = (i for i in range(5))
gl = list(gen)
print(2 in gl) # True
print(1 in gl) # True
迭代器转为List或Tuple,元素不会丢弃。
二、is 和 ==
Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。
==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等,例如下面两个字符串间的比较:
a = -1.0
b = -1.0
print("---", a == b) # --- True
a = id("abc")
b = id("abc")
print("---", a == b) # --- True
is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。
a, b = 5, 5
print(a is b) #True
a, b = 257, 257
print(a is b) # idea edit True
print(a is b) # python edit False
a, b = -6, -6
print(a is b) #False
a, b = -1.0, -1.0
print(a is b) # False
a, b = "abc", "abc"
print(a is b) # True
a, b = "abc 123", "abc 123"
print(a is b) # idea edit True
print(a is b) # python edit False
a, b = [1, 2, 3], [1, 2, 3]
print(a is b) # False
数值型和字符串型的情况下,a is b才为True,当a和b是tuple,list,dict或set型时,a is b为False。
特殊的,在python解释器中,为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。而Python 对小整数的定义是 [-5, 257),只有数字在-5到256之间它们的id才会相等,超过了这个范围就不行了,同样的道理,字符串对象也有一个类似的缓冲池,对于单个字符串,多个字符串则不会相等。
在IDEA编辑器中,略有不同,请自行研究。
三、列表list和字典dict
1) list
- 添加元素
test_list = [1, 2, 3, 4]
test_list.append(5)
print(test_list) # [1, 2, 3, 4, 5]
- 列表相加
test_list = [1, 2, 3, 4]
test_2 = [5, 6]
print(test_list + test_2) # [1, 2, 3, 4, 5, 6]
test_list.extend(test_2)
print(test_list) # 1, 2, 3, 4, 5, 6]
"""
注意:
append 是向列表中添加一个对象object
extend 是把一个序列seq的内容添加到列表中,有点类似java的add_all()
"""
- 元素删除
test_list = [1, 2, 3, 4]
test_list.remove(1)
print(test_list) # [2, 3, 4]
test_list.pop(2)
print(test_list) # [2, 3]
# 按索引删除元素
del test_list[0]
print(test_list) # [3]
- 列表排序
test_list = [3, 1, 2, 4]
sorted(test_list)
print(test_list) #[3, 1, 2, 4]
"""
使用sorted函数,需要赋值给一个新的变量,才能实现排序
"""
sorted_list = sorted(test_list)
print(sorted_list) # [1, 2, 3, 4]
test_list.sort() # 如果对list自身进行排序,直接可得排序之后的列表
print(test_list) # [1, 2, 3, 4]
"""
重复元素去重排序
"""
#1、不改变数组的引用
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]
s = set()
#对原数组进行拷贝,去重时候不会出现对遍历影响
for item in nums[:]:
if item in s:
nums.remove(item)
else:
s.add(item)
print(nums) # [0, 1, 2, 3, 4]
#2、改变数组的引用
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]
l = list(set(nums))
l.sort(key=nums.index)
nums = l
print(nums) # [0, 1, 2, 3, 4]
2) dict
- 添加元素
test_dict = {"a": 1, "b": 2, "c": 3}
test_dict['d'] = 4
print(test_dict) # {'b': 2, 'd': 4, 'c': 3, 'a': 1} 字典是无序的
- 字典相加
"""
使用update方法,将字典分别update一个空字典
"""
test_dict = dict({"a": 1, "b": 2, "c": 3})
test_2 = dict({"c": 6, "d": 4, "e": 5})
new_dict = {}
new_dict.update(test_dict)
new_dict.update(test_2)
print(new_dict) # {'e': 5, 'b': 2, 'c': 6, 'd': 4, 'a': 1}
"""
使用字典的构造函数dict(self, seq=None, **kwargs)
"""
test_dict = dict({"a": 1, "b": 2, "c": 3})
test_2 = dict({"c": 6, "d": 4, "e": 5})
new_dict = dict(test_dict, **test_2)
print(new_dict) # {'c': 6, 'b': 2, 'a': 1, 'd': 4, 'e': 5}
- 元素删除
test_dict = dict({"a": 1, "b": 2, "c": 3})
del test_dict['a']
print(test_dict) # {'c': 3, 'b': 2}
- 字典排序
"""
按照key排序
"""
test_dict = dict({"d": 4, "e": 0, "a": 1, "b": 2, "c": 3})
sorted_dict = sorted(test_dict.items(), key=lambda item: item[0])
print(sorted_dict) # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 0)]
"""
按照value排序
"""
test_dict = dict({"d": 4, "e": 0, "a": 1, "b": 2, "c": 3})
sorted_dict = sorted(test_dict.items(), key=lambda item: item[1])
print(sorted_dict) # [('e', 0), ('a', 1), ('b', 2), ('c', 3), ('d', 4)]
- 有序dict
test_dict = OrderedDict()
test_dict["a"] = 1
test_dict["c"] = 3
test_dict["d"] = 4
test_dict["e"] = 0
test_dict["b"] = 2
print(test_dict.keys()) # odict_keys(['a', 'c', 'd', 'e', 'b'])
print(test_dict.values()) # odict_values([1, 3, 4, 0, 2])
四、元组tuple操作
注意:
1、当元组中一个元素时,一定要在元素后面加上逗号
2、元组中的元素是不允许删除的,但可以使用del语句来删除整个元组
3、元组没有列表中的增、删、改的操作,只有查的操作
"""
创建元素为1个的元组
"""
test_tuple = (1,)
print(test_tuple) # (1,)
"""
元组查询操作,同list
"""
test_tuple = (1, 2, "e", ["a", "b"], {"c": 2}, 0.5)
print(test_tuple[-1]) # 0.5
五、日志模块
\qquad python的日志打印有多种形式,其中介绍一种方式。
- 实现代码如下:
class Logger(object):
def __init__(self, log_file_name, log_level, logger_name):
# 创建一个logger
self.__logger = logging.getLogger(logger_name)
# 指定日志的最低输出级别,默认为WARN级别
self.__logger.setLevel(log_level)
# 创建一个handler用于写入日志文件
file_handler = logging.handlers.TimedRotatingFileHandler(log_file_name, encoding='utf-8')
# file_handler = ConcurrentRotatingFileHandler(log_file_name, encoding='utf-8')
# # 创建一个handler用于输出控制台
# console_handler = logging.StreamHandler()
# 定义handler的输出格式
formatter = logging.Formatter(
'[%(asctime)s] - [logger name :%(name)s] - [%(filename)s file line:%(lineno)d] - %(levelname)s: %(message)s')
file_handler.setFormatter(formatter)
# console_handler.setFormatter(formatter)
# 给logger添加handler
self.__logger.addHandler(file_handler)
# self.__logger.addHandler(console_handler)
def get_log(self):
return self.__logger
- 调用形式如下:
logger = Logger(log_file_name='log.txt', log_level=logging.DEBUG, logger_name="test").get_log()
d = {"a": 1, "b": 2}
logger.debug('dict ... %s' % str(d))
logger.info('testing ... ')
"""
会产生一个log.txt的文件,如果同时设置控制台StreamHandler(),则可在控制台
看到日志打印结果。
"""
六、not 和 None
\qquad 在python中 None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()都相当于False ,即:
not None == not False == not '' == not 0 == not [] == not {} == not ()
\qquad
如果想区分x==[]和x==None,使用if not x:
将会出现问题。
x = []
y = None
print(not x) # True
print(not y) # True
print(x is None) # False
print(y is None) # True
\qquad 另外,is None 和 == None的区别
class Foo:
def __eq__(self, other):
return True
"""
== 取决于__eq__函数内部自定义。
is 比较的是对象ID
"""
if __name__ == '__main__':
f = Foo()
print(f == None) # True
print(f is None) # False
七、文件读写
a) 写文件
- 内容追加
"""
a+ : 以追加的形式写文件
"""
with open(output, 'a+', encoding='utf-8') as f2:
f2.write("xxxx")
- 字符集
"""
字符集设置 encoding = ‘utf-8’
"""
- 实时刷新
with open(output, 'a+', encoding='utf-8') as f:
f.write("xxxx")
f.flush() # 实时刷新
- 多行写入
with open(output, 'a+', encoding='utf-8') as f:
"""
writelines传入列表,但是如果每项后不带\n换行符,则在一行
内写入
"""
f.writelines(["xxxx","bbbbb"])
f.writelines(["cccc\n","dddd\n"])
八、ASCII和字符
\qquad python中使用chr()和ord()函数对ASCII码进行字符转换和反转换。
print(chr(48)) # 0
print(chr(65)) # A
print(ord('a')) # 97
print(ord('-')) # 45
九、列表按照原来顺序去重
former = ["aa","bb","cc","bb","dd","bb","aa"]
latter = list(set(former))
# latter.sort(key=lambda item: former.index(item))
latter.sort(key=former.index)
print(latter)
# ['aa', 'bb', 'cc', 'dd']
十、多线程和队列
import threading
import time
from queue import Queue
class MyThread(threading.Thread):
def __init__(self, _queue, num):
threading.Thread.__init__(self)
self._queue = _queue
self.num = num
def run(self):
while True:
time.sleep(1)
if not self._queue.empty():
data = self._queue.get()
print("Thread %d print data %d ." % (self.num, int(data)))
else:
break
if __name__ == '__main__':
queue = Queue()
for i in range(20):
queue.put(i)
for j in range(5):
MyThread(queue, j).start()
十一、chain、zip、product
"""
zip 将2个集合级联
"""
a = [1, 2, 3]
b = [6, 5, 4]
c = zip(a, b)
print(c) # [(1, 6), (2, 5), (3, 4)]
d = [6 ,5]
e = zip(a, d)
print(e) # [(1, 6), (2, 5)]
"""
product 将两个集合进行笛卡尔
"""
from itertools import product
f = product(a, d)
for each in f:
print(each)
"""
(1, 6)
(1, 5)
(2, 6)
(2, 5)
(3, 6)
(3, 5)
"""
"""
chain 将多个迭代器串联
"""
from itertools import chain
g = chain(a, d)
for each in g:
print(each)
"""
1
2
3
6
5
"""
h = chain(*e) # [(1, 6), (2, 5)] 首先变为2个迭代器[1,6],[2,5]
# 使用chain串联多个迭代器
for each in h:
print(each)
"""
1
6
2
5
"""
十二、UnitTest、Nose、Twist
1、Nose相关链接
http://blog.zhengtianyu.com/index.php/2018/07/04/nosexuexibiji/
http://blog.topspeedsnail.com/archives/3953
也可以显式的指定文件、模块或函数
nosetests only_test_this.py
nosetests test.module
nosetests another.test:TestCase.test_method
nosetests a.test:TestCase
nosetests /path/to/test/file.py:test.function
十三、导包路径
\qquad 一般情况下python工程下主函数所在的py文件放在引用的package的外层,此时主函数py可以直接调用。
工程目录如下:
ImportDemo\
utils\
action_util.py
word_util.py
...
exec.py
action_util.py
class Handler(object):
def hug(self):
print("hug person. ")
word_util.py
class Say(object):
def hello(self):
print("say hello")
from utils.action_util import Handler
t = Handler()
t.hug()
\qquad 此时,执行主函数脚本,不会发生报错,pycharm和python环境下均可执行。
\qquad 但是,如果主函数py脚本,与调用package是同级下,则pycharm下可以正常运行,但是python环境下不可执行,会出现找不到模块。
目录结构如下:
ImportDemo\
utils\
action_util.py
word_util.py
...
exec.py
import sys
sys.path.append('..')
# sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.action_util import Handler
t = Handler()
t.hug()
\qquad
此时需要将sys.path.append('..')
加入环境变量中,等同于sys.path.append(os.path.dirname(os.path.dirname(__file__))
一样可以将父目录加入环境变量,但是却执行不成功,问题是__file__
是相对路径,所以必须使用os.path.abspath(__file__))
。