㈠ python 里有指針的東西嗎
沒有。由於對象機制(對象三種屬性: 實體,類型和值)的引入,Python、java、C#等動態確定變數類型的面向對象語言的使用可以非常靈活。比如我們可以用自省方法來查看內存中以對象形式存在的其它模塊和函數,獲取它們的信息,並對它們進行 操作。用這種方法,你可以定義沒有名稱的函數,不按函數聲明的參數順序調用函數,甚至引用事先並不知道名稱的函數。也就是說除了C/C++,其他語言都不用指針,改為「引用」。
㈡ Python 外部函數調用庫ctypes簡介
一直對不同語言間的交互感興趣,python和C語言又深有淵源,所以對python和c語言交互產生了興趣。
最近了解了python提供的一個外部函數庫 ctypes , 它提供了C語言兼容的幾種數據類型,並且可以允許調用C編譯好的庫。
這里是閱讀相關資料的一個記錄,內容大部分來自 官方文檔 。
ctypes 提供了一些原始的C語言兼容的數據類型,參見下表,其中第一列是在ctypes庫中定義的變數類型,第二列是C語言定義的變數類型,第三列是Python語言在不使用ctypes時定義的變數類型。
創建簡單的ctypes類型如下:
使用 .value 訪問和改變值:
改變指針類型的變數值:
如果需要直接操作內存地址的數據類型:
下面的例子演示了使用C的數組和結構體:
創建指針實例
使用cast()類型轉換
類似於C語言定義函數時,會先定義返回類型,然後具體實現再定義,當遇到下面這種情況時,也需要這么干:
可以簡單地將"so"和"dll"理解成Linux和windows上動態鏈接庫的指代,這里我們以Linux為例。注意,ctypes提供的介面會在不同系統上有出入,比如為了載入動態鏈接庫, 在Linux上提供的是 cdll , 而在Windows上提供的是 windll 和 oledll 。
ctypes會尋找 _as_paramter_ 屬性來用作調用函數的參數傳入,這樣就可以傳入自己定義的類作為參數,示例如下:
用 argtypes 和 restype 來指定調用的函數返回類型。
這里我只是列出了 ctypes 最基礎的部分,還有很多細節請參考官方文檔。
這兩天文章沒有寫,先是早出晚歸出去玩了一整天,然後加班到凌晨3點左右,一天一篇計劃劃水得嚴重啊…
㈢ python有沒有指針
如果您曾經使用過C或C ++等低級語言,那麼您可能已經聽說過指針。指針允許您在部分代碼中創建高效率。它們也會給初學者帶來困惑,並且可能導致各種內存管理錯誤,即使對於專家也是如此。那麼在Python中有指針的存在嗎?
指針廣泛用於C和C ++。本質上,它們是保存另一個變數的內存地址的變數。有關指針的更新,可以考慮在C指針上查看此概述。
為什麼Python沒有指針?
實際上指針為何不存在的原因現在還不知道,也許指針違背了Python的禪宗。指針鼓勵隱含的變化而不是明確的變化。但通常情況下,它們很復雜而不是很簡單,特別是對於初學者。更糟糕的是,當他們用指針指向自己的方法,或做一些非常危險的事情,比如從你無法獲取的的一些變數中讀取數據。
Python更傾向於嘗試從用戶那裡抽象出內存地址來實現具體細節,所以Python通常關注可用性而不是速度。因此,Python中的指針並沒有多大意義。但是在有些情況下,Python會為您提供使用指針的一些好處。
想要理解Python中的指針,需要理解Python實現指針功能的具體細節。簡單來說,需要了解這些知識點:
不可變對象和可變對象【Python中的對象】
Python變數/名稱【Python中的變數】
【在Python中模擬實現指針】
㈣ python 調用c++程序, c++程序如何返回數組給python
C/C++不能直接返回一個數組。這是由於在C/C++中,數組不是一種類型,因此不能被直接返回。
一般有兩種方法來返回一個數組。
第一種方法:
返回一個指向數組的指針,例如char (*retArray)[10]聲明了一個函數retArray,該函數可以返回指向具有10個char元素的數組
第二種方法:
如果你不喜歡用指針的形式返回數組,那麼可以採用返回一個結構的形式。這種形式相對較安全,可以避免忘記釋放指針而造成內存泄露,也可以避免訪問懸掛指針造成的錯誤。但缺點是由於結構是先拷貝再返回,因此如果結構較大時,會影響效率和佔用較大內存。
這是C的限制,Python調用C也是這種情況
㈤ python使用C函數返回的指針
manage_new_object返回類的動態對象,要返回簡單的指針,把manage_new_object改為return_xxx_pointer,具體名字記不得了,反正有這個模板,查閱boost文檔吧。
㈥ python中,能對函數傳遞文件指針類型的參數嗎
如果你用C給Matlab寫過MEX程序,那麼這個問題是很容易理解的(好像每次討論Python問題時我總是把Matlab搬了出來…… 《在Matlab中把struct當成Python中的Dictionary使用》《Matlab和Python的幾種數據類型的比較》)。
既然提到了MEX,就簡單說一下:
一個Matlab可能形如
function ret=add3(a,b,c)
如果在C的層面實現這個函數,就會看到另一種景象:
void mexFunction(int nlhs,mxArray * plhs[],int nrhs,const mxArray * prhs[])
a,b,c三個參數的地址放在一個指針數組里,然後把這個指針數組的首地址作為參數prhs傳遞給函數,這說明Matlab函數的參數是傳遞指針的,而不是值傳遞。
縱然是傳遞的指針,但是卻不能在函數里改變實參的值,因為標記為「const」了。
Python是開放源碼的,我沒有看。所以下面很多東西是猜的。
Python在函數的參數傳遞時用的什麼手法?實驗一下(使用ActivePython2.5):
首先介紹一個重要的函數:
>>> help(id)
Help on built-in function id in mole __builtin__:
id(...)
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
看最後括弧里那句:Hint:it's the object's address.(它是對象的地址)
有了這個函數,下面的事情就方便多了。
>>> a=0
>>> id(a)
3630228
>>> a=1
>>> id(a)
3630216
可以看出,給a賦一次值,a的address就改變了。在C的層面看,(也許真實情況不是下面的樣子,但作為一個類比應該還是可以的):
void * pa;
pa=malloc(sizeof(int));
*(int *)pa=0;
free(pa);
pa=malloc(sizeof(int));
*(int *)pa=1;
Python中每次賦值會改變變數的address,分配新的內存空間,所以Python中對於類型不像C那樣嚴格要求。
下面看看Python函數參數傳遞時到底傳的什麼:
有一個函數:
>>> def changeA(a):
... print id(a)
... a=100
... print id(a)
設定一個變數var1:
>>> var1=10
>>> id(var1)
3630108
>>> changeA(var1)
3630108
3631012
>>> var1
10
調用函數後,從兩次print的結果可以看出,傳遞確實是地址。但是即便如此,在函數內對形參的修改不會對實參造成任何實質的影響,因為對形參的重新賦值,只是改變了形參所指向的內存單元(changeA里兩次調用print id(a)得到不同的結果),卻沒有改變實參的指向。在C的層面看也許類似下面的情節:
void changeA(void * pa)
{
pa=malloc(sizeof(int));
*(int *)pa=100;
free(pa);
}
精通C的你一眼就看出這個函數永遠也改變不了它外面的世界。
也就是說雖然傳遞的是地址,但像changeA這樣的函數改變不了實參的值。
也許會感到困擾?不,我已經在Matlab中習慣了。
一個最典型的例子就是Matlab中刪除結構體成員的rmfield函數(參見《Matlab筆記三則》),
(Matlab版本7.0.1)
如果想刪除結構體patient的name成員,用
rmfield(patient, 'name');
是永遠達不到目的的(就像試圖用雙手抓住自己的領子,把自己提到空中);
迷途知返的做法是:
patient = rmfield(patient, 'name');
㈦ 如何用指針刪除一維數組的負數
給定多個值的數組arr。例如-
[-3,5,1,3,2,10]
我們需要編寫一個刪除數組中所有負值的函數。函數完成執行後,數組應僅由正數組成。
我們需要這樣做,而不創建臨時數組,而僅使用pop方法刪除數組中的任何值。
因此,讓我們為該函數編寫代碼-
示例
為此的代碼將是-
// strip all negatives off the end
while (x.length && x[x.length - 1] < 0) {
x.pop();
}
for (var i = x.length - 1; i >= 0; i--) {
if (x[i] < 0) {
//將此元素替換為最後一個元素(保證為
positive)
x[i] = x[x.length - 1];
x.pop();
}
}
輸出結果
控制台中的輸出將為-
[ 1, 8, 9 ]
基礎教程
HTML基礎教程 HTML5基礎教程 HTML參考手冊 SVG 教程 CSS 教程 CSS 參考手冊 CSS3教程 Bootstrap3 教程 Bootstrap4 教程 Font Awesome圖標 JavaScript 教程 JavaScript 參考手冊 jQuery 教程 AJAX 教程 JSON 教程 AngularJS 教程 ReactJS 教程 NodeJS 教程 Python 教程 C++ 教程 Golang 教程 C 語言教程 PHP 教程 C# 教程 LINQ 教程 Lua 教程 Ruby 教程 Rust 教程 Linux 教程 R 語言教程 Docker 教程 Scala 教程 MatLab 教程 Erlang 教程 Pandas教程 Numpy教程 Matplotlib教程 Flask教程 Java 教程 SpringBoot 教程 JDBC 教程 JSP 教程 Servlet 教程 Maven 教程 Spring 教程 Django 教程 Swift 教程 Kotlin 教程 SQL 教程 MongoDB 教程 SQLite 教程 PostgreSQL 教程 MySql 教程 Redis 教程 Elasticsearch 教程
㈧ python調用c語言動態庫dll/.so中的函數的參數是結構體的問題
java源自C++,C++源自C語言....
各有優點呀,不知道要怎麼回答了,或許樓主是搞C語言的吧,這些語言都各有特點呀...
首先應該清晰,Java是由C++發展而來的,他保留了c++的大部分內容,類似於c++,
但句法更清晰,規模更小,更易學。他是在對多種程式設計語言進行了深入細致研究的
基礎上,據棄了其他語言的不足之處,從根本上解決了c++的固有缺陷,而產生的一種
新的完全方面向對象的語言。
Java和c++的相似之處多於不同之處,但兩種語言問幾處主要的不同使得Java更容易
學習,並且編程環境更為簡單。
因篇幅所限,這里不能完全列出不同之處,僅列出比較顯著的差別:
1.指針
Java無指針,並且增添了自動的內存管理功能,從而有效地防
止了c/c++語言中指針操作失誤,如指針懸空所造成的系統崩潰。
比w操作返回一對象的引用,類似於c++中的引用;在c++中,
new返回一個對象的指針。在Java中無指針,不會遇見下面這樣的
語句:
Mywork?>Mywork();
沒有指針的程式無法訪問不屬於他的內存,消除了在c++
中?些常見的錯誤,這有利於Java程式的安全。
2.多重繼承
c++支持多重繼承,這是c++的一個特徵,他允許多父類派
生一個類。盡管多重繼承功能非常強,但使用復雜,而且會引起許多麻
煩,編譯程式實現他也非常不容易。Java不支持多重繼承,但允許一個
類繼承多個介面(界面),實現了c++多重繼承的功能,又避免了c++的
許多缺陷。
㈨ python ctypes 怎麼處理函數返回的一般指針
test.c(動態庫源代碼)
[cpp] view plain
// 編譯生成動態庫: gcc -g -fPIC -shared -o libtest.so test.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct StructPointerTest
{
char name[20];
int age;
}StructPointerTest, *StructPointer;
StructPointer test() // 返回結構體指針
{
StructPointer p = (StructPointer)malloc(sizeof(StructPointerTest));
strcpy(p->name, "Joe");
p->age = 20;
return p;
}
編譯:gcc -g -fPIC -shared -o libtest.so test.c
call.py(python調用C語言生成的動態庫):
[python] view plain
#!/bin/env python
# coding=UTF-8
from ctypes import *
#python中結構體定義
class StructPointer(Structure):
_fields_ = [("name", c_char * 20), ("age", c_int)]
if __name__ == "__main__":
lib = cdll.LoadLibrary("./libtest.so")
lib.test.restype = POINTER(StructPointer)
p = lib.test()
print "%s: %d" %(p.contents.name, p.contents.age)
最後運行結果:
[plain] view plain
[zcm@c_py #112]$make clean
rm -f *.o libtest.so
[zcm@c_py #113]$make
gcc -g -fPIC -shared -o libtest.so test.c
[zcm@c_py #114]$./call.py
Joe: 20
[zcm@c_py #115]$
㈩ python 怎麼寫通過邏輯指針進行數據切片,找出讀入數據中最新價是偶數的行
對於Perl的一行式perl程序來說,選擇要輸出的、要刪除的、要插入/追加的行是非常容易的事情,因為print/say決定行是否輸出/插入/追加/刪除。雖然簡單,但對於廣泛應用在sed的示例還是可以拿到這里來討論一番。
因為輸出/刪除/插入/追加行都是通過print/say在不同條件下的操作,所以本文只會介紹輸出操作,刪除/插入/追加其實都是同樣的原理。
輸出第一行
$ perl -lne 'print;exit' file.log
輸出第13行
$ perl -ne 'print if $. == 13' file.log
輸出前10行
$ perl -ne 'print if $.<=10' file.log$ perl -ne 'print if 1..10' file.log$ perl -ne '$. <= 10 && print' file.log$ perl -ne 'print; exit if $. == 10' file.log
輸出最後一行
$ perl -ne '$last=$_;END{print $last}' file.log
或者通過文件結尾eof來判斷:
$ perl -ne 'print if eof' file.log
這里的eof函數的作用是:如果下一行讀取到了文件尾部eof,就返回1。否則
輸出倒數10行
這個實現起來可能稍顯復雜,但邏輯很簡單:向一個數組中添加10行元素,如果數組元素個數超過了10,則剔除數組的第一個元素。
$ perl -ne 'push @lines,$_;if(@lines>10){shift @lines;}END{print @lines}' /etc/passwd
這里是shift一個元素來保證"窗口"的穩定性:最多隻有10個元素。另一種穩妥的方式是直接切片,從數組中取最後10個元素:
$ perl -ne 'push @lines,$_;@lines = @lines[@lines-10..$#lines] if @lines>10;END{print @lines}' /etc/passwd
輸出倒數第11行到倒數第2行
有了前一個示例作為基礎,這個需求很容易實現。
保留一個11行元素的數組,最後輸出前10個元素即可。
$ perl -ne 'push @a,$_;shift @a if @a>11;END{print @a[0..$#a-1]}' /etc/passwd
輸出文件的第偶數行
這個很簡單,只需判斷行號的奇偶性即可。
$ perl -ne 'print if $. % 2 == 0' file.log$ perl -ne 'print unless $. % 2' file.log
輸出能匹配的行
$ perl -ne 'print if /regexp/' file.log
輸出兩個匹配之間的行
$ perl -ne 'print if /regexp1/../regexp2/' file.log
輸出匹配行的前一行
只需將每行保留到變數中,如果當前行匹配了,則輸出上一行保存的值。
$ perl -ne '/regexp/ && $last && print $last;$last = $_' file.log
如果想要輸出匹配的前M行,只需把這些數量的行保存到數組中,並不斷地shift剔除就可以。
輸出匹配行的後一行
$ perl -ne '$p && print; $p = /regexp/' file.log
Perl中正則表達式的匹配操作返回的是成功與否的布爾真假,所以$p = /regexp/表示如果匹配了,則$p的值為真,否則為假。
如果$p為真,則下一行將被輸出,且繼續對輸出行進行匹配,如果輸出行仍然能匹配,則繼續輸出下一行。
上面的過程可以改寫成邏輯更為清晰的一行式:
$ perl -ne 'if($p){print;$p=0}++$p if /regexp/' file.log
上面的$p是一個狀態標記變數,如果匹配成功,就標記為真值,並在輸出的時候重置狀態變數。
還可以採用另一種處理邏輯:自己編寫從<>讀取行的while循環,如果匹配了就繼續讀入下一行。因為讀入的下一行可能繼續匹配,所以在while循環中使用redo邏輯回到while循環的開頭。
$ perl -se 'while(<>){if(/$reg/){if(eof){ exit; }print $_ = <>;}redo if /$reg/;}' -- -reg="REGEXP" file.log
輸出匹配行及其後5行
上面採用狀態標記變數$p,這個狀態標記變數可以更深入地使用。
如果匹配了,則$p設置為5,然後輸出後面的行時對$p自減。
$ perl -ne 'if($p){print;$p--}if(/regexp/){$p = 5;print};' file.log
連續行去重
$ perl -ne 'next if "$line" eq "$_";print $line = $_;' file.log