目录
3. Python & Pycharm 文件操作及与C混合编程 3
1. Python & Anaconda安装
下载Python或Anaconda(遵守GPL协议),anaconda包含较全第三方封装库,若安装Python,需将Python安装路径导入系统环境变量,另需手动导入所需库(注意下载对应版本,网址:http://www.lfd.uci.edu/~gohlke/pythonlibs)。
导入库方法:据上述网址下载所需库文件(.whl文件),放在Python安装目录下scripts文件夹中,然后dos命令下输入:pip3.6install”.whl文件路径””.whl文件”;提示”successfully installed”表示安装成功。注意:上述pip3.6对应Python版本,如Python3.6对应pip3.6。
anaconda 下载网址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
python 库安装方法:https://blog.csdn.net/xz1308579340/article/details/68489772
1.2 Pycharm 安装及导入库文件
直接双击pycharm-community.exe进行安装,注意Pycharm与Python版本要对应。
导入库方法:File->Settings->Project->Project Interpreter路径下选择Python安装路径下的Python.exe(若是安装Anaconda,选择Anaconda安装路径下的 Python.exe即可),即可导入Python中的第三方库,已导入库在改页面下有对应显示。
1.3 Pycharm 常用工具栏
控制台:Tools->Python console;
页面背景:File->Settings->Editor->Color Scheme->Python窗口Scheme选项;
字体:File->Settings->Editor->Font窗口;
2. Python & Pycharm 使用注意事项
2.1 Python2x与Python3x区别
Python3x版本叫Python2x版本有较大改动,使用时需注意语法区别,目前网上资料多对应Python2x版本。
简要区别:http://www.jb51.net/article/57956.htm。
2.2 Python语法格式
Python语言中数组下标从0开始,与C语言一致,区别于MATLAB语言。
Python语言中for if等语句无结束标志(如end等),而是由格式判断结束行。
Python语言中范围选择一般不包括后者,如生成[1,5]范围的随机数,实际表示生成从0开始(包含0)到5(不含5)的随机数。
2.3 Pycharm基本操作
库的导入
import numpy:表示导入numpy模块,一个文件导入一次即可;
import numpy,scipy,……:导入多个模块;
import numpy as A:作用与import numpy一样,相当于给numpy起别名,A的作用与numpy完全等效;
from A import B:表示导入模块A中的一个函数B;
from A import *:参考http://m.jb51.net/article/52412.htm;
添加库路径
import sys
sys.path.append(r’D:\Dev_Cpp’)
注释
注释使用 #,注释特定行;三个双引号或单引号可以注释多行;
中文字符
文件中包含中文字符时,需在文件开头添加下述两行代码:
#!/usr/bin/python
#-*-conding:utf-8-*-
3. Python & Pycharm 文件操作及与C混合编程
3.1 Python文件读取及存储
Numpy库数据文件保存及加载:
# ####################################################################
a = numpy.array([1.4, 2, 3, 4, 5, 6])
numpy.save('name',a) # 保存数据文件,文件名为name
c = numpy.load('name.npy') # 加载数据文件 name.npy
# ####################################################################
# ####################################################################
a = numpy.array([1.4, 2, 3, 4, 5, 6])
b = numpy.array([2, 4])
numpy.savez("rr.npz",a, namekey = b)
# 保存多个数组,namekey为数组关键字参数,不设置默认为arr_0 等
c = numpy.load("rr.npz")
print(c["arr_0"])
print(c["namekey"])
# ####################################################################
文件保存读取:
# ####################################################################
numpy.savetxt("a.txt", a) # 保存txt文件
numpy.savetxt("b.txt", a, fmt = "%d", delimiter = ",")
# 保存txt文件,更改保存数据类型为整数,以“,”分割
b = numpy.loadtxt("a.txt") # 读取txt文件
c = numpy.loadtxt("b.txt", delimiter=",") # 与上述保存文件对应
a = numpy.array([1, 2, 3, 4, 5, 6])
numpy.savetxt('name.csv', a, delimiter=',') # 读取csv文件
# ####################################################################
文件读取:
# ####################################################################
a = numpy.genfromtxt('tt.txt',delimiter=',',names=True)
# ####################################################################
Python自带函数的文件读取:
# ####################################################################
with open('name.txt',"w") as f:
f.write("input")
# ####################################################################
mode |
|
“r” | 读方式,只读;若文件不存在,发生异常 |
“w” | 写方式,只写;若文件不存在,则直接创建;若文件存在,则先清空 |
“rb” | 二进制读方式,只读;若文件不存在,发生异常 |
“wb” | 二进制写方式,只写;若文件不存在,则直接创建;若文件存在,则先清空 |
“rt” | 文本读方式,只读;若文件不存在,发生异常 |
“wt” | 文本写方式,只写;若文件不存在,则直接创建;若文件存在,则先清空 |
“rb+” | 二进制读方式,可读写;若文件不存在,发生异常 |
“wb+” | 二进制写方式,可读写;若文件不存在,直接创建;若文件存在,则先清空 |
“a” | 附加写方式,只写; |
“a+” | 附加读写方式,可读写; |
3.2 Python文件调用
调用文件中的类:
# ####################################################################
class mysum(object): # 定义类 文件名为yu.py
num = []
def __int__(self,_list,age):
super(mysum, self).__init__()
self.num = _list
self.age = age
# ######################### 另一个py文件调用上述类
from yu import mysum # 调用yu.py 文件中的mysum 类
mylist = [2, 4]
a = musum(mylist,5)
a._plot()
# ####################################################################
3.3 Python结构体数组
# ####################################################################
pes = numpy.dtype({'names':['name', 'age', 'weight'],'formats':['a6', 'i2', 'f2']},
align=True) # align = True 令结构体数组内存对齐
ape = numpy.array([("zhang", 32, 67.8),("wang", 24, 66.6)], dtype=pes)
print(ape[0]) # 访问
peint(ape[1]["weight"])
# ####################################################################
结构化数组类型:
bytes | b1 |
int | i1,i2,i4,i8 |
unsigned ints | u1,u2,u4,u8 |
floats | f2,f4,f8 |
complex | c8,c16 |
fix long strings | a<n> |
3.4 Python结构体嵌套结构体
# ####################################################################
class st(Structure): # 结构体嵌套结构体
_fields_ = [('a', c_char_p),
('b', c_int)]
age = st()
age.a = bytes('liu',encoding='utf-8') # 字符串
age.b = 23
class person_Info(Structure):
_fields_ = [('x', st), # 结构体类型
('y', c_int),
('z', c_float)]
person_liu = person_Info()
person_liu = age
print(person_liu.x.b)
# ####################################################################
3.5 Python指针使用
class comp(Structure):
_fields_ = [('real', POINTER(c_double)),
('imag', POINTER(c_double))]
class stru(Structure):
_fields_ = [('sco', comp),
('scoo', comp)]
struc = stru()
ar = np.array([1+1j, 2+2j, -3-3j, 4-5j])
# =======ar.real 与 struc.sco.real 隔离 ========
arr = np.array(ar.real, dtype=c_double)
c_arr = np.ctypeslib.as_ctypes(arr)
arr_ptr = cast(c_arr, POINTER(c_double))
struc.sco.real = arr_ptr
# ======== ar.real 与 struc.sco.real 联动 ========
c_arr1 = cast(np.ctypeslib.as_ctypes(np.array(ar.real, dtype=c_double)), POINTER(c_double))
struc.sco.real = c_arr1
3.6 Python与C 混合编程
通过ctypes实现Python与C的混合编程,下载Dev_C++编译器(遵守GPL协议),通过Dev_C++编写编译C代码,生成.dll文件。
Dev_C++编译实现:新建DLL项目->编写C文件->.h文件编写函数定义->编译生成dll文件。
Python调用&返回C数组&指针:
.h文件,函数声明
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
DLLIMPORT void HelloWorld();
DLLIMPORT int _add(int x);
DLLIMPORT int add_int(int x[],int *y);
#endif
.c文件
/* Replace "heu.h"with the name of your header */
#include "heu.h" // .h文件名
#include <windows.h>
#include <stdio.h>
DLLIMPORT void HelloWorld()
{
MessageBox(0,"Hello World from DLL!\n","Hi",MB_ICONINFORMATION);
}
DLLIMPORT int add_int(int num1[], int *num2)
{
int b[4] = {6,7,8,9};
int a = num1[0]+num2[2];
num2[0] = num2[0]+11;
}
.py文件,调用.dll文件
# ####################################################################
import ctypes
ll = numpy.ctypeslib.load_library('D:\Dev_Cpp\lo.dll','dll') # lo.dll文件名
arr = numpy.array([1, 2, 3, 4],dtype = numpy.int)
arr1 = numpy.zeros(4, dtype=numpy.int)
if not arr.flags['C_CONTIGUOUS']: # 若不是C连续内存,强制转换
arr = numpy.ascontiguous(arr, dtype = numpy.dtype)
if not arr1.flags['C_CONTIGUOUS']:
arr1 = numpy.ascontiguous(arr1, dtype = numpy.dtype)
c_arr = numpy.ctypeslib.as_ctypes(arr) # array 转为ctypes类型
c_arr1 = numpy.ctypeslib.as_ctypes(arr1)
ll.add_int(c_arr1, c_arr) # 调用C函数,传递/返回数组地址
print(arr)
print(arr1)
# ####################################################################
Python调用&返回C结构体:
.h头文件
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
DLLIMPORT struct person_Info
{
char *a;
int b;
float c;
};
#endif
.c文件
/* Replace "struc.h"with the name of your header */
#include "struc.h" // .h文件名
#include <windows.h>
#include <stdio.h>
DLLIMPORT struct person_Info fun(struct person_Info uk)
{
printf("%s\n%d\n%f\n",uk.a, uk.b, uk.c);
uk.c = uk.c + 1;
uk.a = "hu";
printf("%s\n%d\n%f\n",uk.a, uk.b, uk.c);
printf("===========================\n");
return uk;
}
.py文件
# ####################################################################
hh = numpy.ctypeslib.load_library('D:\Dev_Cpp\lo.dll','dll')
class person_Info(Structure):
_fields_ = [('x',c_char_p), # 传递字符串
('y',c_int),
('z',c_float)]
person_liu = person_Info(bytes('liu',encoding='utf-8'), 25, 65.0)
person_h = person_Info()
person_h.x = bytes('ut',encoding='utf-8') # 传递字符串(str转bytes)
person_h.y = c_int(26) # bytes 转str:str(b, encoding = 'utf8')
person_h.z = c_float(57.8)
hh.fun.restype = person_Info
r = hh.fun(person_h)
t = hh.fun(person_liu)
# ####################################################################
另,若x对应数组,C代码里直接修改x对应类型定义即可,py代码参考如下:
# ####################################################################
hh = numpy.ctypeslib.load_library('D:\Dev_Cpp\lo.dll','dll')
class person_Info(Structure):
_fields_ = [('x',c_char_p), # 传递字符串
('y',c_int),
('z',c_float*2)]
person_liu = person_Info(bytes('liu',encoding='utf-8'), 25, numpy.ctypeslib.as_ctypes(numpy.array([65.0, 33], dtype = c_float)))
person_h = person_Info()
person_h.x = bytes('ut',encoding='utf-8') # 传递字符串(str转bytes)
person_h.y = c_int(26) # bytes 转str:str(b, encoding = 'utf8')
inz = numpy.array([1, 2],dtype = c_float) # 注意此处dtype类型
person_h.z = numpy.ctypeslib.as_ctypes(inz) # 传递指针,参考上述数组指针
hh.fun.restype = person_Info
r = hh.fun(person_h)
t = hh.fun(person_liu)
print(r.z)
# ####################################################################
Python传递数值参量,返回结构体:
.h头文件
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
typedef struct // 定义结构体,与python结构体对应
{
int a;
float b[2];
}result;
DLLIMPORT result fun(int x, float b); // 接收数值参量
#endif
.c文件
/* Replace "struc.h"with the name of your header */
#include "struc.h" // .h文件名
#include <windows.h>
#include <stdio.h>
DLLIMPORT result fun(int x, float y)
{
result s;
s.a = x;
s.b[0] = y + 1.0;
s.b[1] = y + 2.0;
return s;
}
.py文件
# ####################################################################
hh = numpy.ctypeslib.load_library('D:\Dev_Cpp\lo.dll','dll')
class person_Info(Structure):
_fields_ = [('y',c_int),
('z',c_float*2)]
hh.fun.restype = person_Info # 返回类型
hh.fun.argtyprs = [c_int, c_float]
res = hh.fun(23, 34.0)
print(res.y)
print(res.z[1])
dd = numpy.array(numpy.fromiter(res.z,dtype=numpy.float,count=2)) # 返回转成数组
# fromiter 仅可用于多个数据,单个数值不可用
print(dd[0])
# ####################################################################
Ctypes模块
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Python & Pycharm 基本函数
4.1 类型转换
int(x [,base ]) 将x转换为一个整数
long(x [,base ]) 将x转换为一个长整数
float(x ) 将x转换到一个浮点数
complex(real [,imag ]) 创建一个复数
str(x ) 将对象 x 转换为字符串
repr(x ) 将对象 x 转换为表达式字符串
eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s ) 将序列 s 转换为一个元组
list(s ) 将序列 s 转换为一个列表
chr(x ) 将一个整数转换为一个字符
unichr(x ) 将一个整数转换为Unicode字符
ord(x ) 将一个字符转换为它的整数值
hex(x ) 将一个整数转换为一个十六进制字符串
oct(x ) 将一个整数转换为一个八进制字符串