Python函數參數傳遞機制問題在本質上是調用函數(過程)和被調用函數(過程)在調用發生時進行通信的方法問題。基本的參數傳遞
成都創新互聯專業為企業提供新撫網站建設、新撫做網站、新撫網站設計、新撫網站制作等企業網站建設、網頁設計與制作、新撫企業網站模板建站服務,10多年新撫做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
機制有兩種:值傳遞和引用傳遞。值傳遞(passl-by-value)過程中,被調函數的形式參數作為被調函數的局部變量處理,即在堆棧中開
辟了內存空間以存放由主調函數放進來的實參的值,從而成為了實參的一個副本。值傳遞的特點是被調函數對形式參數的任何操作都是作
為局部變量進行,不會影響主調函數的實參變量的值。(推薦學習:Python視頻教程)
引用傳遞(pass-by-reference)過程中,被調函數的形式參數雖然也作為局部變量在堆棧中開辟了內存空間,但是這時存放的是由主調函
數放進來的實參變量的地址。被調函數對形參的任何操作都被處理成間接尋址,即通過堆棧中存放的地址訪問主調函數中的實參變量。正
因為如此,被調函數對形參做的任何操作都影響了主調函數中的實參變量。
//test1.c#?include?stdio.h#?include?stdlib.hstruct?Student
{????char?name[30];????float?fScore[3];
};void?Display(struct?Student?su){????printf("-----Information------\n");????printf("Name:%s",su.name);????printf("Chinese:%.2f\n",su.fScore[0]);????printf("Math:%.2f\n",su.fScore[1]);????printf("English:%.2f",su.fScore[2]);????printf("平均分數為:%.2f\n",(su.fScore[0]+su.fScore[1],su.fScore[2])/3);
}
#先上代碼再解釋
static?PyObject?*keywdarg_parrot(PyObject?*self,?PyObject?*args,?PyObject?*keywds)
{
int?voltage;
char?*state?=?"a?stiff";
char?*action?=?"voom";
char?*type?=?"Norwegian?Blue";
static?char?*kwlist[]?=?{"voltage",?"state",?"action",?"type",?NULL};
if?(!PyArg_ParseTupleAndKeywords(args,?keywds,?"i|sss",?kwlist,
voltage,?state,?action,?type))
return?NULL;
printf("--?This?parrot?wouldn't?%s?if?you?put?%i?Volts?through?it.\n",
action,?voltage);
printf("--?Lovely?plumage,?the?%s?--?It's?%s!\n",?type,?state);
Py_INCREF(Py_None);
return?Py_None;
}
static?PyMethodDef?keywdarg_methods[]?=?{
/*?The?cast?of?the?function?is?necessary?since?PyCFunction?values
*?only?take?two?PyObject*?parameters,?and?keywdarg_parrot()?takes
*?three.
*/
{"parrot",?(PyCFunction)keywdarg_parrot,?METH_VARARGS?|?METH_KEYWORDS,
"Print?a?lovely?skit?to?standard?output."},
{NULL,?NULL,?0,?NULL}???/*?sentinel?*/
};
PyObject?*?initkeywdarg(void)
{
/*?Create?the?module?and?add?the?functions?*/
return?Py_InitModule("keywdarg",?keywdarg_methods);
}
這是一個函數(keywdarg_parrot)即使用了元組參數,也使用了字典參數的例子。例子出自Python2.7.2的文檔。具體在:
Python v2.7.2 documentation #187;Extending and Embedding the Python
Interpreter
這個頁面下。文檔里面有一些關于C/C++與Python交互的介紹和例子,還是比較詳細的。傳遞字典參量要注意,
{"parrot",?(PyCFunction)keywdarg_parrot,?METH_VARARGS?|?METH_KEYWORDS,
"Print?a?lovely?skit?to?standard?output."},
這里的METH_VARARGS | METH_KEYWORDS,與普通的不同。解析用:
PyArg_ParseTupleAndKeywords(args,?keywds,?"i|sss",?kwlist,
voltage,?state,?action,?type)
其中的四個變量要提前聲明好,這里分別是int,str,str,str類型的。int對應的是args接受到的值。string的都是keywds里面的,它們都是有初始值的。kwlist是變量的名字,就是在python里調用的時候使用的keyword名稱。照著例子的模式可以改成其它的,能用的。具體是怎么工作的,其實我也太明白。
Python代碼是這樣的調用的時候:
print?keywdarg.parrot(10,"LHJ",'HKJ','ER')
print?keywdarg.parrot(10,"LHJ",'HKJ')
print?keywdarg.parrot(10,"LHJ",type='KJ')
輸出分別是:
-- This parrot wouldn't HKJ if you put 10 Volts through it.
-- Lovely plumage, the ER -- It's LHJ!
None
-- This parrot wouldn't HKJ if you put 10 Volts through it.
-- Lovely plumage, the Norwegian Blue -- It's LHJ!
None
-- This parrot wouldn't voom if you put 10 Volts through it.
-- Lovely plumage, the KJ -- It's LHJ!
None
第二次調用省略掉了變量,也能正常執行。第三次調用,變量type本來是第四位的,現在變成了keyword并寫在了第三位,是python代碼里調用的常見形式:keyword不講順序,省略掉的keyword使用了默認值。
就這些了,其它的你再看一下Python的文檔吧。
python的函數參數傳遞是"引用傳遞(地址傳遞)"。
python中賦值語句的過程(x = 1):先申請一段內存分配給一個整型對象來存儲數據1,然后讓變量x去指向這個對象,實際上就是指向這段內存(這里有點和C語言中的指針類似)。
在Python中,會為每個層次生成一個符號表,里層能調用外層中的變量,而外層不能調用里層中的變量,并且當外層和里層有同名變量時,外層變量會被里層變量屏蔽掉。函數? 調用 ?會為函數局部變量生成一個新的符號表。
局部變量:作用于該函數內部,一旦函數執行完成,該變量就被回收。
全局變量:它是在函數外部定義的,作用域是整個文件。全局變量可以直接在函數里面應用,但是如果要在函數內部改變全局變量,必須使用global關鍵字進行聲明。
注意 :默認值在函數? 定義 ?作用域被解析
在定義函數時,就已經執行力它的局部變量
python中不可變類型是共享內存地址的:把相同的兩個不可變類型數據賦給兩個不同變量a,b,a,b在內存中的地址是一樣的。
Python是解釋性語言, 底層就是用c實現的, 所以用python調用C是很容易的, 下面就總結一下各種調用的方法, 給出例子, 所有例子都在ubuntu9.10, python2.6下試過
1. Python 調用 C (base)
想在python中調用c函數, 如這兒的fact
#include Python.h
int fact(int n)
{
if (n = 1)
return 1;
else
return n * fact(n - 1);
}
PyObject* wrap_fact(PyObject* self, PyObject* args)
{
int n, result;
if (! PyArg_ParseTuple(args, "i:fact", n))
return NULL;
result = fact(n);
return Py_BuildValue("i", result);
}
static PyMethodDef exampleMethods[] =
{
{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
{NULL, NULL}
};
void initexample()
{
PyObject* m;
m = Py_InitModule("example", exampleMethods);
}
把這段代碼存為wrapper.c, 編成so庫,
gcc -fPIC wrapper.c -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config
然后在有此so庫的目錄, 進入python, 可以如下使用
import example
example.fact(4)
2. Python 調用 C++ (base)
在python中調用C++類成員函數, 如下調用TestFact類中的fact函數,
#include Python.h
class TestFact{
public:
TestFact(){};
~TestFact(){};
int fact(int n);
};
int TestFact::fact(int n)
{
if (n = 1)
return 1;
else
return n * (n - 1);
}
int fact(int n)
{
TestFact t;
return t.fact(n);
}
PyObject* wrap_fact(PyObject* self, PyObject* args)
{
int n, result;
if (! PyArg_ParseTuple(args, "i:fact", n))
return NULL;
result = fact(n);
return Py_BuildValue("i", result);
}
static PyMethodDef exampleMethods[] =
{
{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
{NULL, NULL}
};
extern "C" //不加會導致找不到initexample
void initexample()
{
PyObject* m;
m = Py_InitModule("example", exampleMethods);
}
把這段代碼存為wrapper.cpp, 編成so庫,
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config
然后在有此so庫的目錄, 進入python, 可以如下使用
import example
example.fact(4)
3. Python 調用 C++ (Boost.Python)
Boost庫是非常強大的庫, 其中的python庫可以用來封裝c++被python調用, 功能比較強大, 不但可以封裝函數還能封裝類, 類成員.
首先在ubuntu下安裝boost.python, apt-get install libboost-python-dev
#include boost/python.hpp
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello)
{
using namespace boost::python;
def("greet", greet);
}
把代碼存為hello.cpp, 編譯成so庫
g++ hello.cpp -o hello.so -shared -I/usr/include/python2.5 -I/usr/lib/python2.5/config -lboost_python-gcc42-mt-1_34_1
此處python路徑設為你的python路徑, 并且必須加-lboost_python-gcc42-mt-1_34_1, 這個庫名不一定是這個, 去/user/lib查
然后在有此so庫的目錄, 進入python, 可以如下使用
import hello
hello.greet()
'hello, world'
4. python 調用 c++ (ctypes)
ctypes is an advanced ffi (Foreign Function Interface) package for Python 2.3 and higher. In Python 2.5 it is already included.
ctypes allows to call functions in dlls/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python. It is even possible to implement C callback functions in pure Python.
#include Python.h
class TestFact{
public:
TestFact(){};
~TestFact(){};
int fact(int n);
};
int TestFact::fact(int n)
{
if (n = 1)
return 1;
else
return n * (n - 1);
}
extern "C"
int fact(int n)
{
TestFact t;
return t.fact(n);
}
將代碼存為wrapper.cpp不用寫python接口封裝, 直接編譯成so庫,
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config
進入python, 可以如下使用
import ctypes
pdll = ctypes.CDLL('/home/ubuntu/tmp/example.so')
pdll.fact(4)
12
本文題目:python向c函數傳參 python 類之間傳值
當前URL:http://m.kartarina.com/article32/hgcjsc.html
成都網站建設公司_創新互聯,為您提供網站設計、網站策劃、定制開發、商城網站、自適應網站、品牌網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯