[转载] python学习笔记
日期: 2020-11-27 分类: 个人收藏 455次阅读
参考链接: Python | a += b并不总是a = a + b
官网http://www.python.org/
官网library http://docs.python.org/library/
PyPI https://pypi.python.org/pypi
中文手册,适合快速入门 http://download.csdn.net/detail/xiarendeniao/4236870
python cook book中文版 http://download.csdn.net/detail/XIARENDENIAO/3231793
1.数值尤其是实数很方便、字符串操作很炫、列表 a = complex(1,0.4)
a.real
a.imag
Unicode()
字符串前加上r/R表示常规字符串,加上u/U表示unicode字符串 列表的append()方法在列表末尾加一个新元素
2.流程控制
while:
if:
if xxx:
...
elif yyy:
...
elif xxx:
...
else:
...
for
range()
break continue 循环中的else
pass
3.函数
1)def funA(para) 没有return语句时函数返回None,参数传递进去的是引用
2)默认参数,默认参数是列表、字典、类实例时要小心
3)不定参数,def funB(king, *arguments, **keywords) 不带关键字的参数值存在元组arguments中,关键字跟参数值存在字典keywords中。其实是元组封装和序列拆封的一个结合。
4)
def funC(para1, para2, para3) 下面的调用把列表元素分散成函数参数funcC(*list)
5)匿名函数 lambda arg1,arg2...:<expression>
特点:创建一个函数对象,但是没有赋值给标识符(不同于def);lambda是表达式,不是语句;“:”后面只能是一个表达式 6)if ‘ok’ in (‘y’, ‘ye’, ‘yes’): xxxxx 关键字in的用法
7)f = bambda x: x*2 等效于 def f(x): return x*2
4.数据结构
1)[] help(list) append(x) extend(L) insert(i,x) remove(x) pop([i]) index(x) count(x) sort() reverse()
2)List的函数化编程 filter() map() reduce()
3)列表推导式 aimTags = [aimTag for aimTag in aimTags if aimTag not in filterAimTags]
4)del删除列表切片或者整个变量
5)() help(tuple) 元组tuple,其中元素和字符串一样不能改变。元组、字符串、列表都是序列。 Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义。这是新手常犯的错误
6){} help(dict) 字典 keys() has_key() 可用以键值对元组为元素的列表直接构造字典
7)循环 字典:for k, v in xxx.iteritems():… for item in xxx.items():... 序列:for i, v in enumerate([‘tic’, ‘tac’, ‘toe’]):… 同时循环多个序列:for q, a in zip(questions, answers):…
8)in not in is is not a<b==c and or not
9)相同类型的序列对象之间可以用< > ==进行比较
10)判断变量类型的两种方法:isinstance(var,int) type(var).__name__=="int"
多种类型判断,isinstance(s,(str,unicode))当s是常规字符串或者unicode字符串都会返回True
11)在循环中删除list元素时尤其要注意出问题,for i in listA:... listA.remove(i)是会有问题的,删除一个元素之后后面的元素就前移了;for i in len(listA):...del listA[i]也会有问题,删除元素后长度变化,循环会越界
filter(lambda x:x !=4,listA)这种方式比较优雅
listA = [ i for i in listA if i !=4] 也不错,或者直接创建一个新的列表算球 效率:
1)"if k in my_dict" 优于 "if my_dict.has_key(k)"
2)"for k in my_dict" 优于 "for k in my_dict.keys()",也优于"for k in [....]"
12)set是dict的一种实现 https://docs.python.org/2/library/stdtypes.html#set-types-set-frozenset
>>> s1 = set([1,2,3,4,5])
>>> s2 = set([3,4,5,6,7,8])
>>> s1|s2
set([1, 2, 3, 4, 5, 6, 7, 8])
>>> s1-s2
set([1, 2])
>>> s2-s1
set([8, 6, 7])
5.模块
1)模块名由全局变量__name__得到,文件fibo.py可以作为fibo模块被import fibo导入到其他文件或者解释器中,fibo.py中函数明明必须以fib开头
2)import变体: from fibo import fib, fib2 然后不用前缀直接使用函数
3)sys.path sys.ps1 sys.ps2
4)内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表,列出了所有类型的名称:变量,模块,函数,等等
help()也有类似的作用
5)包 import packet1.packet2.module from packet1.packet2 import module from packet1.packet2.module import functionA
6)import 语句按如下条件进行转换:执行 from package import * 时,如果包中的 __init__.py 代码定义了一个名为 __all__ 的列表,就会按照列表中给出的模块名进行导入
7)sys.path打印出当前搜索python库的路径,可以在程序中用sys.path.append("/xxx/xxx/xxx")来添加新的搜索路径
8)安装python模块时可以用easy_install,卸载easy_install -m pkg_name
9)用__doc__可以得到某模块、函数、对象的说明,用__name__可以得到名字(典型用法:if __name__=='__main__': ...)
6.IO
1)str() unicode() repr() repr() print rjust() ljust() center() zfill() xxx%v xxx%(v1,v2) 打印复杂对象时可用pprint模块(调试时很有用)
对于自定义的类型,要支持pprint需要提供__repr__方法。对于pprint的结果不想直接给标准输出(pprint.pprint(var))可以用pprint.pformat(var). 2)f = open(“fileName”, “w”) w r a r+ Win和Macintosh平台还有一个模式”b”
f.read(size)
f.readline()
f.write(string)
f.writelines(list)
f.tell()
f.seek(offset, from_what) from_what:0开头 1当前 2末尾 offset:byte数http://www.linuxidc.com/Linux/2007-12/9644p3.htm
f.close()
linecache模块可以方便的获取文件某行数据,在http-server端使用时要注意,尤其是操作大文件很危险,并发情况下很容易就让机器内存耗尽、系统直接挂掉(本人血的教训)
文件操作时shutil比较好用
os.walk()遍历目录下所有文件
3)pickle模块(不是只能写入文件中)
封装(pickling)类似于php的序列化:pickle.dump(objectX, fileHandle)
拆封(unpickling)类似于php反序列化:objectX = pickle.load(fileHandle)
msgpack(easy_install msgpack-python)比pickle和cpickle都好用一些,速度较快
msgpack.dump(my_var, file('test_file_name','w'))
msgpack.load(file('test_file_name','r'))
4)raw_input()接受用户输入 7.class
1)以两个下划线下头、以不超过一个下划线结尾成员变量和成员函数都是私有的,父类的私有成员在子类中不可访问
2)调用父类的方法:1>ParentClass.FuncName(self,args) 2>super(ChildName,self).FuncName(args) 第二种方法的使用必须保证类是从object继承下来的,否则super会报错
3)静态方法定义,在方法名前一行写上@staticmethod。可以通过类名直接调用。
#!/bin/python
#encoding=utf8
class A(object):
def __init__(self, a, b):
self.a = a
self.b = b
def show(self):
print "A::show() a=%s b=%s" % (self.a,self.b)
class B(A):
def __init__(self, a, b, c):
#A.__init__(self,a,b)
super(B,self).__init__(a,b) #super这种用法要求父类必须是从object继承的
self.c = c
if __name__ == "__main__":
b = B(1,2,3)
print b.a,b.b,b.c
b.show()
#输出
xudongsong@sysdev:~$ python class_test.py
1 2 3
A::show() a=1 b=2
8.编码
常见的编码转换分为以下几种情况:
unicode->其它编码
例如:a为unicode编码 要转为gb2312。a.encode('gb2312')
其它编码->unicode
例如:a为gb2312编码,要转为unicode。 unicode(a, 'gb2312')或a.decode('gb2312')
编码1 -> 编码2
可以先转为unicode再转为编码2
如gb2312转big5
unicode(a, 'gb2312').encode('big5')
判断字符串的编码
isinstance(s, str) 用来判断是否为一般字符串
isinstance(s, unicode) 用来判断是否为unicode
如果一个字符串已经是unicode了,再执行unicode转换有时会出错(并不都出错)
>>> str2 = u"sfdasfafasf"
>>> type(str2)
<type 'unicode'>
>>> isinstance(str2,str)
False
>>> isinstance(str2,unicode)
True
>>> type(str2)
<type 'unicode'>
>>> str3 = "safafasdf"
>>> type(str3)
<type 'str'>
>>> isinstance(str3,unicode)
False
>>> isinstance(str3,str)
True
>>> str4 = r'asdfafadf'
>>> isinstance(str4,str)
True
>>> isinstance(str4,unicode)
False
>>> type(str4)
<type 'str'>
可以写一个通用的转成unicode函数:
def u(s, encoding):
if isinstance(s, unicode):
return s
else:
return unicode(s, encoding)
9.线程
1)要让子线程跟着父线程一起退出,可以对子线程调用setDaemon()
2)对子线程调用join()方法可以让父线程等到子线程退出之后再退出
3)ctrl+c只能被父线程捕获到(子线程不能调用信号捕获函数signal.signal(signal,function)),对子线程调用join()会导致父线程捕获不到ctrl+c,需要子线程退出后才能捕获到
附:成应元老师关于python信号的邮件 参考 http://stackoverflow.com/questions/631441/interruptible-thread-join-in-python From http://docs.python.org/library/signal.html#module-signal: Some care must be taken if both signals and threads are used in the same program. The fundamental thing to remember in using signals and threads simultaneously is: always perform signal() operations in the main thread of execution. Any thread can perform an alarm(), getsignal(), pause(), setitimer() or getitimer(); only the main thread can set a new signal handler, and the main thread will be the only one to receive signals (this is enforced by the Python signal module, even if the underlying thread implementation supports sending signals to individual threads). This means that signals can’t be used as a means of inter-thread communication. Use locks instead. 总是在主线程调用signal设置信号处理器,主线程将是唯一处理信号的线程。因此不要把线程间通信寄托在信号上,而应该用锁。 The second, from http://docs.python.org/library/thread.html#module-thread: Threads interact strangely with interrupts: the KeyboardInterrupt exception will be received by an arbitrary thread. (When the signal module is available, interrupts always go to the main thread.) 当导入signal模块时, KeyboardInterrupt异常总是由主线程收到,否则KeyboardInterrupt异常会被任意一个线程接到。 直接按Ctrl+C会导致Python接收到SIGINT信号,转成KeyboardInterrupt异常在某个线程抛出,如果还有线程没有被 setDaemon,则这些线程照运行不误。如果用kill送出非SIGINT信号,且该信号没设置处理函数,则整个进程挂掉,不管有多少个线程 还没完成。
下面是signal的一个使用范例:
>>> import signal
>>> def f():
... signal.signal(signal.SIGINT, sighandler)
... signal.signal(signal.SIGTERM, sighandler)
... while True:
... time.sleep(1)
...
>>> def sighandler(signum,frame):
... print signum,frame
...
>>> f()
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>
signal的设置和清除:
import signal, time
term = False
def sighandler(signum, frame):
print "terminate signal received..."
global term
term = True
def set_signal():
signal.signal(signal.SIGTERM, sighandler)
signal.signal(signal.SIGINT, sighandler)
def clear_signal():
signal.signal(signal.SIGTERM, 0)
signal.signal(signal.SIGINT, 0)
set_signal()
while not term:
print "hello"
time.sleep(1)
print "jumped out of while loop"
clear_signal()
term = False
for i in range(5):
if term:
break
else:
print "hello, again"
time.sleep(1)
[dongsong@bogon python_study]$ python signal_test.py
hello
hello
hello
^Cterminate signal received...
jumped out of while loop
hello, again
hello, again
^C
[dongsong@bogon python_study]$ 多进程程序使用信号时,要想让父进程捕获信号并对子进程做一些操作,应该在子进程启动完成以后再注册信号处理函数,否则子进程继承父进程的地址空间,也会有该信号处理函数,程序会混乱不堪
from multiprocessing import Process, Pipe
import logging, time, signal
g_logLevel = logging.DEBUG
g_logFormat = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d]%(message)s"
def f(conn):
conn.send([42, None, 'hello'])
#conn.close()
logging.basicConfig(level=g_logLevel,format=g_logFormat,stream=None)
logging.debug("hello,world")
def f2():
while True:
print "hello,world"
time.sleep(1)
termFlag = False
def sighandler(signum, frame):
print "terminate signal received..."
global termFlag
termFlag = True
if __name__ == '__main__':
# parent_conn, child_conn = Pipe()
# p = Process(target=f, args=(child_conn,))
# p.start()
# print parent_conn.recv() # prints "[42, None, 'hello']"
# print parent_conn.recv()
# p.join()
p = Process(target=f2)
p.start()
signal.signal(signal.SIGTERM, sighandler)
signal.signal(signal.SIGINT, sighandler)
while not termFlag:
time.sleep(0.5)
print "jump out of the main loop"
p.terminate()
p.join()
10.Python 的内建函数locals() 。它返回的字典对所有局部变量的名称与值进行映射
11.扩展位置参数
def func(*args): ...
在参数名之前使用一个星号,就是让函数接受任意多的位置参数。
python把参数收集到一个元组中,作为变量args。显式声明的参数之外如果没有位置参数,这个参数就作为一个空元组。
关联item 3.4
12.扩展关键字参数(扩展键参数)
def accept(**kwargs): ...
python在参数名之前使用2个星号来支持任意多的关键字参数。
注意:kwargs是一个正常的python字典类型,包含参数名和值。如果没有更多的关键字参数,kwargs就是一个空字典。
位置参数和关键字参数参考这篇文章:http://blog.csdn.net/qinyilang
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
精华推荐