把之前的python 使用方法全部汇总到这里
转载自这里
C/C++ 与Python
C调用python接口方法
主要是参考下面两篇博文
使用c语言调用python小结
Python实例浅谈之三Python与C/ C++ 相互调用
需要注意的是,
1.如果提示undefined reference to Py_XXXX
说明没有正确加载python的库,根据python的版本,在makefile里加入-lpython2.7
2.如果PyImport_ImportModule返回的指针为空,一定是python模块的路径搞错了,这里我开始直接给
PyImport_ImportModule的参数传的是python模块的绝对路径,返回为空。后来使用下面两句解决了问题,
应该是需要先调用第一句加入python模块的路径,PyImport_ImportModule只负责加载模块名称,不包括路径
PyRun_SimpleString("import sys" ) ;
PyRun_SimpleString("sys.path.append('./')" ) ;
PyImport_ImportModule('voc_eva l' ) ;
python与c++混合编程调试方法
这里主要是调试py-faster-rcnn,其他类似
单纯使用pdb可以调试python代码,但是无法调试其调用的c++代码。
如果要调试c++代码,使用如下指令
gdb –args python test.py
具体步骤:
1.使用指令,并且r进去,让进程跑起来
2.由于此时caffe.so并没有加载进来,所以,可能会出现即使在cpp里下断点也无法跟踪的情况,这里可以先手动ctrl+c把进程断开,再设置断点,让caffe.so加载进来。
所以,这一步是下断点,如b caffe/src/caffe/solver.cpp:228
3.c,进去cpp里即可
下划线
变量
主要存在四种情形
1. object # public
2. object # special, python system use, user should not define like it
3. __object # private (name mangling during runtime)
4. _object # obey python coding convention, consider it as private
核心风格:避免用下划线作为变量名的开始。
函数
前带_的变量: 标明是一个私有函数, 只用于标明
前带两个_ ,后带两个_ 的函数: 标明是特殊函数
多层目录模块调用
转载自这里
1. 将导入模块所在目录(../model/模块)添加到系统环境变量path下,可添加多个
import sys
sys.path.append("../model" )
from model import a
注意:不管什么样的引用,建议直接使用这种方法,避免发生引用模块里import的问题。
(所有被引用模块的调用会优先查找当前执行目录下的文件,找不到再去找所有环境变量的目录!)
程序结构如下:
– src
|– model
| |– a.py
| |– b.py
|– test.py
a模块 调用了同级目录的b –> import b
test模块 调用a模块时出错 –> from model import a
出错:在test当前目录运行时找不到b模块。
2.引用模块在 当前目录的同级以及所包含的子目录中:
2.1. 直接import 同级文件.子文件.引用模块
2.2. from 同级文件.子文件 import 引用模块
列表等分
转载自这里
这里主要借助itertools模块里的izip和iziplongest方法,代码如下
from itertools import zip_longest
chunk_list = lambda a_list, n: zip_longest(*[iter(a_list)]*n)
result_groups = list(chunk_list([x for x in range(100 )], 8 ))
Out[12 ]:
[(0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ),
(8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ),
(16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 ),
(24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ),
(32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 ),
(40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 ),
(48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 ),
(56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 ),
(64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 ),
(72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 ),
(80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 ),
(88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 ),
(96 , 97 , 98 , 99 , None , None , None , None )]
这里借助了迭代器,关于*[iter(a_list)]*n ,参考了stackoverflow里的精彩说明,如下
iter() is an iterator over a sequence. [x]
* n produces a list containing n quantity of x, i.e. a list of length n, where each element is x. *arg unpacks a sequence into arguments for a function call. Therefore you’re passing the same iterator 3 times to zip(), and it pulls an item from the iterator each time.
x = iter([1,2,3,4,5,6,7,8,9])
print zip(x, x, x)
最终产生了一个等分list的方法。
等分list可以用来批量处理数据,如等分目录下的文件等。
数字前补0
转载自这里
python中有一个zfill方法用来给字符串前面补0,非常有用
n = "123"
s = n.zfill(5 )
assert s == "00123"
zfill()也可以给负数补0
n = "-123"
s = n.zfill(5 )
assert s == "-0123"
对于纯数字,我们也可以通过格式化的方式来补0
n = 123
s = "%05d" % n
assert s == "00123"
生成voc数据集的脚本代码
__author__ = 'xiaobanderui'
from xml.dom import minidom
import numpy as np
import cv2
imgpath = u'e:/VOC2007/JPEGImages/'
txtpath = u'e:/data.txt'
xml_path = u'e:/VOC2007/Annotations/'
lastname = u'begin'
foldername = u'VOC2007'
num = 0
valid_num = 0
cv2.namedWindow('img' , cv2.WINDOW_NORMAL)
with open(txtpath, 'r' ) as fr:
for item in fr.readlines():
num += 1
print 'processing %d' % num
item = item.strip().decode('gbk' )
str_item = item.split(' ' )
img =cv2.imread((imgpath + str_item[0 ]).encode('gbk' ), cv2.IMREAD_UNCHANGED)
ht. wd. cn = img.shape
xmin = int(float(str_item[2 ]))
xmax = int(float(str_item[3 ]))
ymin = int(float(str_item[4 ]))
ymax = int(float(str_item[5 ]))
cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0 , 0 , 255 ), 2 )
cv2.imshow('img' , img)
cv2.waitKey()
if xmin >= xmax or ymin >= ymax or xmin < 0 or ymin < 0 or xmax < 0 or ymax < 0 or xmin >= wd or xmax >= wd or ymin >= ht or ymax >= ht
continue
oldx1 =xmin
oldx2 = xmax
newxmin = wd - oldx2 - 1
newxmax = wd - oldx1 - 1
if newxmin >= newxmax
continue
valid_num += 1
if str_item[0 ] == last_name:
object_node = doc.createElem('object' )
rootNode = doc.appendChild(object_node)
node = doc.createElem('name' )
node_text = doc.createTextNode(str_item[1 ])
node.appendChild(node_text)
object_ode = doc.appendChild(node)
'''
其他类似添加,不再赘述
'''
else :
if vars().has_key('rootNode' ):
fw_xml = open(xml_path + file_full_name[0 ] + '.xml' , 'w' )
fw_xml.write(doc.toprettyxml(encoding='utf-8' ))
fw_xml.close()
node = doc.createElem('name' )
node_text = doc.createTextNode(str_item[1 ])
node.appendChild(node_text)
object_ode = doc.appendChild(node)
fw_xml = open(xml_path + file_full_name[0 ] + '.xml' , 'w' )
fw_xml.write(doc.toprettyxml(encoding='utf-8' ))
fw_xml.close()
编译错误总结
代码缩进问题,错误信息如下
IndentationError: unindent does not match any outer indentation level
类型转换问题
如下字串转为int会有错误
str = '123.456'
x = int (str )
错误信息如下
invalid literal for int() with base 10
百度了一下,发现python里的int()只接受纯数字的转换,这里有的字串有‘.’,所以会报错,做如下更改即可
str = '123.456'
x = round(float (str ))
numpy
savetxt
使用numpy的savetxt保存的数据维度>=3时,会出现错误,比如保存一个三通道的数组就会出错,这里可以采用每个通道分别保存的方式
np .savetxt (filename , array [0,:,:] )
np .savetxt (filename , array [1,:,:] )
np .savetxt (filename , array [2,:,:] )
目录、文件操作
判断目录、文件是否存在
转载自这里
这篇文章主要介绍了Python判断文件和文件夹是否存在的方法,本文还讲解了判断是否为文件或者目录的方法、os.path.lexist的作用、FTP中判断文件或目录是否存在等内容,需要的朋友可以参考下
1.python判断文件和文件夹是否存在、创建文件夹,代码如下
>>> import os
>>> os.path.exists('d:/assist' )
True
>>> os.path.exists('d:/assist/getTeacherList.py' )
True
>>> os.path.isfile('d:/assist' )
False
>>> os.path.isfile('d:/assist/getTeacherList.py' )
True
>>> os.makedirs('d:/assist/set' )
>>> os.path.exists('d:/assist/set' )
True
2.python判断文件是否存在,代码如下
import os
filename = r'/home/tim/workspace/test.txt'
if os.path.exists(filename):
message = 'OK, the "%s" file exists.'
else :
message = "Sorry, I cannot find the " %s" file."
print message % filename
3.如何用Python判断文件是否存在
使用os.path.exists()方法可以直接判断文件是否存在,代码如下
>>> import os
>>> os.path.exists(r'C:\1.TXT' )
False
>>>
如果存在返回值为True,如果不存在则返回False
4.python判断文件夹是否存在,代码如下
$ python
Python 2.7 .3 (default, Jan 2 2013 , 16 :53 :07 )
[GCC 4.7 .2 ] on linux2
Type "help" , "copyright" , "credits" or "license" for more information.
>>> import os
>>>
>>>
>>> tobecheckdir = r'/home/tim/workspace'
>>> os.path.isdir(tobecheckdir)
True
>>>
5.python检查文件是否存在,以及路径是否为文件
from os import path, access, R_OK
PATH='./file.txt'
if path.exists(PATH) and path.isfile(PATH) and access(PATH, R_OK):
print "File exists and is readable"
else :
print "Either file is missing or is not readable"
你也可以通过下面的方式实现:
def file_exists (filename) :
try :
with open(filename) as f:
return True
except IOError:
return False
6.python判断文件和文件夹是否存在
import os
os .path.isfile('test.txt' ) #如果不存在就返回False
os .path.exists(directory) #如果目录不存在就返回False
7.os.path.lexist
还有os.path.lexists(path)
对broken的link file也返回True.
8.python FTP判断文件夹是否存在
python怎样判断文件夹是否存在?广大网友给出了答案:
使用ftp库就可以了,下面是Python核心编程上的例子:
>>> from ftplib import FTP
>>> f = FTP('ftp.python.org' )
>>> f.login('anonymous' , 'guido@python.org' )
'230 Guest login ok, access restrictions apply.'
>>> f.dir()
dir结果中无此文件,就是不存在,或者如下:
try:
f.retrbinary('RETR %s' % FILE ,open (FILE , 'wb ').write)
except ftplib.error_perm:
print 'ERROR : cannot read file "%s" ' % FILE 40 os.unlink(FILE )
不能读此文件,也视为不存在。
命名规范
转载自这里
常量
常量名所有字母大写,由下划线连接各个单词,如
WHITE = 0 XFFFFFF
THIS_IS_A_CONSTANT = 1
变量
普通变量###
全部小写,由下划线连接各个单词,如:
color = WHITE
this_is_a_variable = 1
保护成员变量
单下划线作前缀,意思是只有类对象和子类对象自己能访问到这些变量,且不能用’from module import *’导入。如:
_name =name
私有成员变量
双下划线作前缀,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
__ha =h
全局变量
大写字母,单词之间用_分割。
对于from M import *导入语句,如果想阻止导入模块内的全局变量可以使用旧有的规范,在全局变量上加一个前导的下划线
NUMBER
COLOR_WRITE
注意:
(1) 不论是类成员变量还是全局变量,均不使用 m 或 g 前缀
(2)变量名不应带有类型信息,因为 Python 是动态类型语言。如 iValue、names_list、dict_obj 等都是不好的命名。
函数
普通函数
与普通变量一致,函数名应该为小写,可以用下划线风格单词以增加可读性。
混合大小写仅被允许用于这种风格已经占据优势的时候,以便保持向后兼容
myfunctio ()
my_example_function ()
myName ()
私有函数
以双下划线开头。如:
__get_name()
函数的参数
总使用“self”作为实例方法的第一个参数。总使用“cls”作为类方法的第一个参数。
如果一个函数的参数名称和保留的关键字冲突,通常使用一个后缀下划线好于使用缩写或奇怪的拼写。
模块:
应该是简短的、小写的名字,单词之间用_分割。模块就是指文件
hello.py
ad_stats.py
类
类名单词首字母大写,不使用下划线连接单词,也不加入 C、T 等前缀
实例用小写字母
class MyClass (object )
包
命名方式同模块,是文件夹
特定命名方式:xxx
主要是指 xxx 形式的系统保留字命名法。项目中也可以使用这种命名,它的意义在于这种形式的变量是只读的,这种形式的类成员函数尽量不要重载。如
class Base (object) :
def __init__ (self, id, parent = None) :
self.__id__ = id
self.__parent__ = parent
def __message__ (self, msgid) :
其中 id 、parent 和 message 都采用了系统保留字命名法。
编码问题
目前遇到的最头疼的问题,没有之一
先是一篇简要介绍,链接在这里http://in355hz.iteye.com/blog/1860787
最近业务中需要用 Python 写一些脚本。尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息。
很快,我就遇到了异常:
UnicodeEncodeError: 'ascii ' codec can't encode characters in position 0 -3 : ordinal not in range (128 )
为了解决问题,我花时间去研究了一下 Python 的字符编码处理。网上也有不少文章讲 Python 的字符编码,但是我看过一遍,觉得自己可以讲得更明白些。
下面先复述一下 Python 字符串的基础,熟悉此内容的可以跳过。
对应 C/C++ 的 char 和 wchar_t, Python 也有两种字符串类型,str 与 unicode:
import string
s = '关关雎鸠'
u = u'关关雎鸠'
print isinstance(s, str)
print isinstance(u, unicode)
print s.__class__
print u.__class__
前面的申明:# -- coding: utf-8 - - 表明,上面的 Python 代码由 utf-8 编码。
为了保证输出不会在 linux 终端上显示乱码,需要设置好 linux 的环境变量:export LANG=en_US.UTF-8
如果你和我一样是使用 SecureCRT,请设置 Session Options/Terminal/Appearance/Character Encoding 为 UTF-8 ,保证能够正确的解码 linux 终端的输出。
两个 Python 字符串类型间可以用 encode / decode 方法转换:
print s.decode('utf-8' )
print u.encode('utf-8' )
为什么从 unicode 转 str 是 encode,而反过来叫 decode
因为 Python 认为 16 位的 unicode 才是字符的唯一内码,而大家常用的字符集如 gb2312,gb18030/gbk,utf-8,以及 ascii 都是字符的二进制(字节)编码形式。把字符从 unicode 转换成二进制编码,当然是要 encode。
反过来,在 Python 中出现的 str 都是用字符集编码的 ansi 字符串。Python 本身并不知道 str 的编码,需要由开发者指定正确的字符集 decode。
(补充一句,其实 Python 是可以知道 str 编码的。因为我们在代码前面申明了 # -- coding: utf-8 - -,这表明代码中的 str 都是用 utf-8 编码的,我不知道 Python 为什么不这样做。)
如果用错误的字符集来 encode/decode 会怎样?
u.encode('ascii' )
u.encode('gbk' )
s.decode('ascii' )
s.decode('gbk' )
这就遇到了我在本文开头贴出的异常:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-3: ordinal not in range(128)
现在我们知道了这是个字符串编码异常。接下来, 为什么 Python 这么容易出现字符串编/解码异常?
这要提到处理 Python 编码时容易遇到的两个陷阱。第一个是有关字符串连接的:
s = '关关雎鸠'
u = u'关关雎鸠'
s + u
简单的字符串连接也会出现解码错误?
陷阱一:在进行同时包含 str 与 unicode 的运算时,Python 一律都把 str 转换成 unicode 再运算,当然,运算结果也都是 unicode。
由于 Python 事先并不知道 str 的编码,它只能使用 sys.getdefaultencoding() 编码去 decode。在我的印象里,sys.getdefaultencoding() 的值总是 ‘ascii’ ——显然,如果需要转换的 str 有中文,一定会出现错误。
除了字符串连接,% 运算的结果也是一样的:
"中文:%s" % s
"中文:%s" % u
u"中文:%s" % u
u"中文:%s" % s
我不理解为什么 sys.getdefaultencoding() 与环境变量 L A N G 全 无 关 系 。 如 果 P y t h o n 用 L A N G 全 无 关 系 。 如 果 P y t h o n 用 <script type="math/tex" id="MathJax-Element-3">LANG 全无关系。如果 Python 用 LANG 设置 sys.getdefaultencoding() 的值,那么至少开发者遇到 UnicodeDecodeError 的几率会降低 50%。
另外,就像前面说的,我也怀疑为什么 Python 在这里不参考 # -- coding: utf-8 - - ,因为 Python 在运行前总是会检查你的代码,这保证了代码里定义的 str 一定是 utf-8 。
对于这个问题,我的唯一建议是在代码里的中文字符串前写上 u。另外,在 Python 3 已经取消了 str,让所有的字符串都是 unicode ——这也许是个正确的决定。
其实,sys.getdefaultencoding() 的值是可以用“后门”方式修改的,我不是特别推荐这个解决方案,但是还是贴一下,因为后面有用:
import sys
s = '关关雎鸠'
u = u'关关雎鸠'
reload(sys)
sys.setdefaultencoding('utf-8' )
s + u
"中文:%s" % u
u"中文:%s" % s
可以看到,问题魔术般的解决了。但是注意! sys.setdefaultencoding() 的效果是全局的,如果你的代码由几个不同编码的 Python 文件组成,用这种方法只是按下了葫芦浮起了瓢,让问题变得复杂。
另一个陷阱是有关标准输出的。
刚刚怎么来着?我一直说要设置正确的 linux L A N G 环 境 变 量 。 那 么 , 设 置 错 误 的 L A N G 环 境 变 量 。 那 么 , 设 置 错 误 的 <script type="math/tex" id="MathJax-Element-4">LANG 环境变量。那么,设置错误的 LANG,比如 zh_CN.GBK 会怎样?(避免终端的影响,请把 SecureCRT 也设置成相同的字符集。)
显然会是乱码,但是不是所有输出都是乱码。
import string
s = '关关雎鸠'
u = u'关关雎鸠'
print s
print u
为什么是 unicode 而不是 str 的字符显示是正确的? 首先我们需要了解 print。与所有语言一样,这个 Python 命令实际上是把字符打印到标准输出流 —— sys.stdout。而 Python 在这里变了个魔术,它会按照 sys.stdout.encoding 来给 unicode 编码,而把 str 直接输出,扔给操作系统去解决。
这也是为什么要设置 linux $LANG 环境变量与 SecureCRT 一致,否则这些字符会被 SecureCRT 再转换一次,才会交给桌面的 Windows 系统用编码 CP936 或者说 GBK 来显示。
通常情况,sys.stdout.encoding 的值与 linux $LANG 环境变量保持一致:
import sys
print sys.stdout.encoding
u = u'关关雎鸠'
print u
但是,这里有 陷阱二:一旦你的 Python 代码是用管道 / 子进程方式运行,sys.stdout.encoding 就会失效,让你重新遇到 UnicodeEncodeError。
比如,用管道方式运行上面的 example4.py 代码:
python -u example5.py | more
UnicodeEncodeError: 'ascii ' codec can't encode characters in position 0 -3 : ordinal not in range (128 )
None
可以看到,第一:sys.stdout.encoding 的值变成了 None;第二:Python 在 print 时会尝试用 ascii 去编码 unicode.
由于 ascii 字符集不能用来表示中文字符,这里当然会编码失败。
怎么解决这个问题? 不知道别人是怎么搞定的,总之我用了一个丑陋的办法:
import os
import sys
import codecs
if sys.stdout.encoding is None :
enc = os.environ['LANG' ].split('.' )[1 ]
sys.stdout = codecs.getwriter(enc)(sys.stdout)
u = u'关关雎鸠'
print u
这个方法仍然有个副作用:直接输出中文 str 会失败,因为 codecs 模块的 writer 与 sys.stdout 的行为相反,它会把所有的 str 用 sys.getdefaultencoding() 的字符集转换成 unicode 输出。
# 这个是 str 的字符串
s = '关关雎鸠'
# 输出 str 字符串, 异常
print s # UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
显然,sys.getdefaultencoding() 的值是 ‘ascii’, 编码失败。
解决办法就像 example3.py 里说的,你要么给 str 加上 u 申明成 unicode,要么通过“后门”去修改 sys.getdefaultencoding():
# 使得 sys.getdefaultencoding() 的值为 'utf-8'
reload(sys) # reload 才能调用 setdefaultencoding 方法
sys.setdefaultencoding('utf-8' ) # 设置 'utf-8'
# 这个是 str 的字符串
s = '关关雎鸠'
# 输出 str 字符串, OK
print s # 关关雎鸠
总而言之,在 Python 2 下进行中文输入输出是个危机四伏的事,特别是在你的代码里混合使用 str 与 unicode 时。
有些模块,例如 json,会直接返回 unicode 类型的字符串,让你的 % 运算需要进行字符解码而失败。而有些会直接返回 str, 你需要知道它们的真实编码,特别是在 print 的时候。
为了避免一些陷阱,上文中说过,最好的办法就是在 Python 代码里永远使用 u 定义中文字符串。另外,如果你的代码需要用管道 / 子进程方式运行,则需要用到 example6.py 里的技巧。
后来,为了统一Windows和Linux上的编码,不管什么字符串,我都会在前面加上u,把它们全部强制转化为Unicode。但是,在打印类似list和dict这些数据结构的时候,显示中文字符遇到了问题,只能显示unicode编码,无法显示中文。
解决办法转载自这里http://blog.csdn.net/xiaobei4929/article/details/38734047
在从元组转换到字符串时,中文字符前会出现u’例子’类似这种,具体可参考第二个文章,需要手动去除u一切就都正常了
[u'\u773c' , u'\u8179\u90e8' , u'\u4e94\u5b98' , u'\u53e3\u8154' , u'\u8179\u90e8' ,
u'\u53e3\u8154' ]
str_symptom = str(all_symptom).replace('u\'' ,'\'' )
str_symptom.decode("unicode-escape" )
['眼' , '腹部' , '五官' , '口腔' , '腹部' , '口腔' ]
另外,对于dict这种无序表,可以使用OrderedDict来代替,具体可以参考廖雪峰的python教程 ,非常棒
其他的一些小结
这里有一个爱可可老师的分享python-snippets
类与属性
参考这篇博客
主要是这句话有用
getattr(object, name[,default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
multiprocessing里的Process模块,多线程调用非常的恶心,有些错误,即使添加了print还是无法达到追踪的效果,有时只能改掉多线程的调用方式
列表、字典
使用list初始化dict的方法是
d =dict.fromkeys(l, 0)
得到一个值全为0的字典
对于字典而言,dict[‘x’] =1的操作,如果dict中没有’x’这个键,那么这时就会创建1个新的item