ArcGIS Python編程案例(1)-Python語言基礎(chǔ)

前言 ||| 第二章 使用ArcPy編寫腳本


Python支持大部分在其他語言中出現(xiàn)的編程結(jié)構(gòu)缝彬。在本章內(nèi)容中,我們將會涉及到許多Python支持的編程結(jié)構(gòu)非洲。我們將會首先介紹如何創(chuàng)建一個(gè)新的Python腳本以及如何修改已有腳本褐奴。之后我們將深入了解Python的語言特性锯仪,比如添加注釋拐纱,創(chuàng)建變量铜异,變量賦值以及Python的自動代碼補(bǔ)齊功能等,了解這些內(nèi)容將讓你在使用Python編程的時(shí)候更為簡便秸架。
接下來我們會介紹Python內(nèi)置的數(shù)據(jù)類型揍庄,包括字符型,數(shù)值型东抹,列表和字典等蚂子。類和對象是面向?qū)ο缶幊毯蚉ython語言中兩個(gè)基本的概念沃测。你在ArcGIS中編寫地理處理腳本時(shí)會經(jīng)常使用到上述這些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
另外缆镣,我們還將介紹條件語句和循環(huán)語句以及with語句芽突,這些語句在涉及到ArcPy數(shù)據(jù)訪問模塊(Data Acccess module)中新的游標(biāo)(cursor)對象時(shí)會經(jīng)常使用。最后你還會了解到如何訪問模塊董瞻,這些模塊可以為Python提供更多附加功能。

該部分包含以下內(nèi)容:

  • 如何創(chuàng)建并編輯Python腳本
  • Python語言特性
  • 注釋和變量
  • Python內(nèi)置數(shù)據(jù)類型(字符田巴,數(shù)字钠糊,列表和字典)
  • 復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
  • 循環(huán)語句
  • Python其他功能

IDLE

我在前言中提到過,ArcGIS桌面軟件安裝后壹哺,Python以及用于編寫代碼的IDLE工具也會一同安裝抄伍。IDLE是集成開發(fā)環(huán)境的縮寫(Integrated DeveLopment Environment)。由于IDLE在每一個(gè)ArcGIS桌面軟件安裝環(huán)境中都可以使用管宵,我們使用IDLE開發(fā)環(huán)境來編寫本書中的大部分代碼截珍,才外還會使用ArcGIS軟件中內(nèi)置的Python窗口。你作為程序員還可能會更鐘意其他的開發(fā)工具箩朴,你也可以使用這些工具來編寫代碼岗喉。

Python shell窗口

點(diǎn)擊開始 | 所有程序 | ArcGIS | Python2.7 | IDLE打開Python的IDLE開發(fā)環(huán)境。注意Python版本會因?yàn)榘惭b的ArcGIS軟件版本不同而不同炸庞。比如钱床,ArcGIS10.0版本安裝的是Python2.6,而ArcGIS 10.1版本安裝的則是Python2.7埠居。
Python的shell窗口類似于下面的截圖:

Python的shell窗口用于顯示腳本生成的結(jié)果消息和錯(cuò)誤消息查牌。對于初學(xué)者來講纲爸,通常會誤認(rèn)為地處理腳本代碼是在shell窗口中編寫会通。事實(shí)上并非如此。你需要打開另一個(gè)單獨(dú)的代碼窗口來保存你的腳本怀读。
盡管shell窗口不能用來編寫完整腳本代碼绎橘,但可以以交互方式來即時(shí)獲取代碼反饋信息胁孙。ArcGIS軟件中包含一個(gè)內(nèi)置Python shell窗口也是使用相同的方式。我們將在下個(gè)章節(jié)來介紹ArcGIS Python 窗口金踪。

Python 腳本窗口

在IDLE中浊洞,腳本代碼編寫是在一個(gè)稱作Python 腳本窗口(Python script window)的獨(dú)立窗體中完成。點(diǎn)擊IDLE shell窗口中的File | New Window來打開一個(gè)新的代碼窗口胡岔。Python腳本窗口如下圖所示:

在這個(gè)新打開的腳本窗口中你就可以編寫代碼了法希。每個(gè)腳本需要保存到本地磁盤或者網(wǎng)絡(luò)驅(qū)動器中。腳本文件默認(rèn)的文件擴(kuò)展名為.py靶瘸。

編輯已有Python腳本

右鍵單擊已有的Python腳本文件選擇Edit with IDLE苫亦,會彈出一個(gè)新的shell窗口以及載入腳本代碼內(nèi)容的Python腳本編輯器毛肋。如下面的截圖:

在這個(gè)示例中,我們已經(jīng)在IDLE中載入了ListFeatureClasses.py腳本文件屋剑。代碼內(nèi)容出現(xiàn)在腳本窗口中:

現(xiàn)在腳本窗口已經(jīng)打開润匙,你就可以開始編寫或修改代碼了。你還可以在IDLE中執(zhí)行一些簡單的代碼調(diào)試工作唉匾。代碼調(diào)試是指發(fā)現(xiàn)并修改代碼中錯(cuò)誤的過程孕讳。

IDLE中運(yùn)行腳本

在IDLE代碼窗口中編寫完地理處理腳本或者打開了一個(gè)腳本文件之后,你就可以在IDLE中執(zhí)行代碼巍膘。運(yùn)行腳本之前厂财,你可以先在IDLE中進(jìn)行代碼的語法檢查。在代碼窗口中峡懈,點(diǎn)擊Run | Check Module來執(zhí)行語法檢查璃饱。
所有的語法錯(cuò)誤都會顯示在shell窗口中。如果沒有發(fā)現(xiàn)任何語法錯(cuò)誤的話肪康,你將只會看到彈出的shell窗口荚恶。雖然IDLE可以用來檢查語法錯(cuò)誤,但是并沒有提供邏輯錯(cuò)誤檢查工具以及像PythonWin或者Wingware的開發(fā)環(huán)境提供的高級調(diào)試功能磷支。
確認(rèn)代碼中沒有語法錯(cuò)誤后谒撼,你就可以運(yùn)行腳本啦。點(diǎn)擊Run | Run Module在運(yùn)行腳本:

所有的錯(cuò)誤消息以及print語句和系統(tǒng)消息結(jié)果都會顯示在shell窗口中齐唆。print語句可以將字符串輸出到shell窗口中嗤栓。該語句通常用于更新一個(gè)正在運(yùn)行腳本的狀態(tài)或者代碼調(diào)試。

Python語言基礎(chǔ)

為了能夠更好地編寫ArcGIS地理處理腳本箍邮,你需要先了解一些基本的Python語言結(jié)構(gòu)茉帅。盡管相對其他大部分編程語言,Python更容易學(xué)習(xí)锭弊,但是仍需要花費(fèi)一定時(shí)間來學(xué)習(xí)并熟練使用堪澎。該部分內(nèi)容將向你介紹如何創(chuàng)建變量,如何給變量賦不同數(shù)據(jù)類型的值味滞,如何理解賦值給變量的不同數(shù)據(jù)類型樱蛤,如何使用不同類型的語句,如何使用對象剑鞍,如何讀寫文件以及如何導(dǎo)入第三方的Python模塊昨凡。

注釋

Python腳本需要遵循一個(gè)通用的結(jié)構(gòu)。每個(gè)腳本的開頭部分應(yīng)作為說明文檔蚁署,用以詳細(xì)描述腳本名稱便脊,作者以及腳本功能的總體描述。說明文檔部分在Python中可以通過注釋功能來完成光戈。注釋指用來添加到腳本中作為腳本功能說明性文檔的代碼語句哪痰。這些代碼以#或者##開始遂赠,后面跟著你需要說明解釋的文本內(nèi)容。Python解釋器不會處理這類代碼晌杰。它們只是解釋說明代碼意義跷睦。如下圖所示,注釋行代碼用紅色字體顯示肋演。你也應(yīng)該嘗試在腳本中添加注釋來描述腳本中的重要部分抑诸。無論對你或?qū)ζ渌绦騿T這對今后修改代碼都是非常有用的。

導(dǎo)入模塊

盡管Python包含了大量的內(nèi)置功能惋啃,你還是會經(jīng)常需要訪問一些專門的功能包哼鬓, 功能包又包含在一些外部模塊中。舉個(gè)例子边灭,Math模塊包含了與數(shù)值處理有關(guān)的功能,R模塊則提供了數(shù)據(jù)統(tǒng)計(jì)分析的功能健盒。使用import語句導(dǎo)入模塊绒瘦。編寫ArcGIS地處理腳本時(shí),通常就需要導(dǎo)入ArcPy模塊扣癣,該模塊是用于訪問ArcGIS中提供的GIS工具和函數(shù)的Python包惰帽。import語句會是腳本中的第一行代碼(不包括注釋部分):

import arcpy,os
變量

從高層面來說,變量可以看做是腳本運(yùn)行過程中用來存儲值的計(jì)算機(jī)內(nèi)存區(qū)域父虑。在Python中该酗,通過給定名稱和值來定義變量。變量賦值之后只要簡單地引用變量名稱士嚎,就可以在腳本中的不同位置來獲取該變量值呜魄。比如,你創(chuàng)建了一個(gè)包含要素類名稱的變量莱衩,該變量之后被Buffer工具調(diào)用生成了一個(gè)新的要素集爵嗅。只要簡單地給定一個(gè)名稱,然后緊跟著賦值運(yùn)算符(=)和要賦的值就可以創(chuàng)建一個(gè)變量:

fcParcels = "Parcels"
fcStreets = "Streets"

下表說明了變量名和通過上面的示例代碼賦值給變量名的變量值的關(guān)系:

變量名 變量值
fcParcels Parcels
fcStreets Streets

你在創(chuàng)建變量時(shí)候必須遵守一些命名規(guī)則笨蚁,主要包含以下內(nèi)容:

  • 使用字母睹晒,數(shù)字和下劃線
  • 首字母必須為字母
  • 除了下劃線不能包含其他特殊字符
  • 不能使用Python關(guān)鍵字

大概有幾十個(gè)Python關(guān)鍵字是必須要避免使用的,包括class,if,for,while等等括细。
下面是一些合法的變量名稱的例子:

  • featureClassParcel
  • fieldPopulation
  • field2
  • ssn
  • my_name
    下面是一些非法的變量名稱的例子:
  • class (使用了Python關(guān)鍵字)
  • return (使用了Python關(guān)鍵字)
  • $featureClass (包含特殊字符伪很,必須以字母開頭)
  • 2fields (必須以字母開頭)
  • parcels&Streets (包含特殊字符)

Python語言是區(qū)分大小寫的,因此需要特別注意腳本中變量命名和大小寫奋单。對于Python新人來說锉试,大小寫問題很可能是最為常見的錯(cuò)誤原因,因此遇到代碼錯(cuò)誤時(shí)需要考慮到這種情況辱匿。我們看一個(gè)例子键痛。下面的三個(gè)變量的變量名稱除了大小寫不同之外是一樣的炫彩,但Python仍然認(rèn)為是三個(gè)不同的變量。

mapsize = "22x34"
MapSize = "8x11"
Mapsize = "36x48"

如果打印這三個(gè)變量:

print mapsize
print MapSize
print Mapsize

運(yùn)行結(jié)果如下:

22x34
8x11
36x48

Python中變量名稱需要在整個(gè)腳本中保持一致絮短。推薦是采用駝峰式命名江兢,即變量名稱的首個(gè)單詞全部采用小寫,后續(xù)的每個(gè)單詞的首字母大寫丁频。下面以fieldOwnerName的變量名舉例說明杉允。首個(gè)單詞(field)全部是小寫,后面跟的第二個(gè)單詞(``Owner)和第三個(gè)單詞(Name`)都是采用首字母大寫的形式席里。
Python中變量類型是動態(tài)的叔磷。動態(tài)類型(Dynamic typing)意味著你可以只定義變量名稱和并賦值給它,而不需要定義變量的數(shù)據(jù)類型奖磁。常用的數(shù)據(jù)類型包括:

數(shù)據(jù)類型 示例
字符型 "Streets" fcName="Streets"
數(shù)值型 3.14 percChange=3.14
布爾型 True ftrChanged=true
列表 Streets,Parcels,Streams lstFC=["Streets","Parcels","Streams"]
字典 '0':Streets,'1':Parcels dictFC={'0':Streets,'1':Parcels }
對象 Extent spatialExt=map.extent

我們將在后面的內(nèi)容中詳細(xì)介紹數(shù)據(jù)類型改基。
C#中你需要先定義變量的名稱和類型才能使用。在Python中只要給定變量名稱和值之后就可以使用咖为。Python會在后臺確定變量所包含的數(shù)據(jù)類型秕狰。
舉個(gè)例子,在下面的代碼示例中躁染,我們創(chuàng)建了一個(gè)aTouchdown的變量鸣哀,該變量被定義為整型,也就意味著變量只能接受整型數(shù)據(jù)吞彤。我們給這個(gè)變量賦值為6:

int aTouchdown;
aTouchdown = 6;

在Python中同一變量可以動態(tài)賦值我衬。Python解釋器會動態(tài)地處理賦給變量的數(shù)據(jù)類型:

aTouchdown = 6

你編寫的ArcGIS Python地理處理腳本中需要經(jīng)常引用本地計(jì)算機(jī)或者共享服務(wù)器上的數(shù)據(jù)集的位置。變量中的數(shù)據(jù)集地址通常由路徑組成饰恕。Python中路徑名稱是一類特殊情況需要特別說明挠羔。反斜線(\)是Python中保留的轉(zhuǎn)義字符和行連接符,因此在定義路徑變量時(shí)需要使用兩個(gè)反斜線(\)或者一個(gè)斜線(/)或是在使用單個(gè)反斜線時(shí)需增加字母r前綴懂盐。下面舉例說明這一問題褥赊。
不正確的路徑引用:

fcParcels = "c:\Data\Parcels.shp"

正確的路徑引用:

fcParcels = "c:/Data/Parcels.shp"
fcParcels = "c:\\Data\\Parcels.shp"
fcParcels = r"c:\Data\Parcels.shp"

有時(shí)候你知道腳本中需要一個(gè)變量,但是又沒有必要事先了解要賦給變量的是什么數(shù)據(jù)莉恼。在這種情況下拌喉,你就可以先簡單地定義一個(gè)變量而不賦值給它。腳本運(yùn)行中賦給變量的值也可以更改俐银。
變量可以保存許多不同的數(shù)據(jù)類型尿背,既包括像字符型和數(shù)值型這樣的基本數(shù)據(jù)類型(primitive datatype),也可以包括像列表捶惜,字典甚至對象這樣復(fù)雜的數(shù)據(jù)類型田藐。接下來我們將介紹可以賦值給變量的不同的數(shù)據(jù)類型以及Python提供的數(shù)據(jù)操作方法。

內(nèi)置數(shù)據(jù)類型

Python包含許多內(nèi)置的數(shù)據(jù)類型。我們首先介紹的是字符型(string)汽久。我們已經(jīng)見過一些字符型變量的例子鹤竭,不過這些變量還可以執(zhí)行許多操作方法,讓我們進(jìn)一步了解這一數(shù)據(jù)類型景醇。
字符串
字符串是用于存儲和表示文本信息的有序字符集合臀稚。簡單地講就是字符串變量保存文本內(nèi)容。字符串括在單引號或雙引號內(nèi)賦值給變量三痰。字符串可以是名稱吧寺,要素類名稱,where條件語句以及其他可以用文本表示的情況散劫。
字符操作
Python中提供了很多字符串的操作方法稚机。字符串連接就是最為常用的功能之一,并且容易實(shí)現(xiàn)获搏。使用+運(yùn)算符就可以將運(yùn)算符兩邊的字符串合并為一個(gè)新的字符串變量:

shpStreets = "c:\\GISData\\Streets" + ".shp"
print shpStreets

運(yùn)行結(jié)果如下:

c:\GISData\Streets.shp

你可以使用Python提供的==(兩個(gè)連續(xù)的=)運(yùn)算符來測試字符串是否相等赖条。不要混淆了相等運(yùn)算符和賦值運(yùn)算符,后者使用單個(gè)等號符號常熙。相等運(yùn)算符是用于判斷兩個(gè)變量是否相等谋币,而賦值運(yùn)算符則是賦值給變量:

firstName = "Eric"
lastName = "Pimpler"
firstName == lastName

運(yùn)行結(jié)果如下:

False

你還可以使用in運(yùn)算符來判斷字符串的包含關(guān)系,如果第一個(gè)算子包含在第二個(gè)算子中的話將返回True症概。

fcName = "Floodplain.shp"
print ".shp" in fcName
print ".shx" in fcName

運(yùn)行結(jié)果如下:

True
False

我之前簡單提到過字符串是有序的字符集合。這意味著什么早芭?這將意味著我們可以獲取字符串中的單個(gè)字符或者子字符串彼城。在Python中,獲取單個(gè)字符的操作稱作索引(indexing)退个,而獲取連續(xù)字符的時(shí)候操作切片(slicing)募壕。
字符串中的字符可以通過括在方括號內(nèi)的數(shù)字索引值來獲取。比如你可以使用fc[0]來獲得獲取fc變量中字符串的第一個(gè)字符语盈。負(fù)的位置數(shù)值用于從字符串末端開始反向向前查找舱馅。在這種情況下,字符串最后一個(gè)字符的索引號為-1刀荒。使用索引會創(chuàng)建一個(gè)新的變量來保存返回的字符:

fc = "Floodplain.shp"
print fc[0]
print fc[10]
print fc[13]

運(yùn)行結(jié)果如下:

'F'
'.'
'p'

下圖說明了字符串作為字符的有序集合的組織形式代嗤,第一個(gè)字符占據(jù)位置0,第二個(gè)字符占據(jù)位置1缠借,后續(xù)的字符依次占據(jù)下一個(gè)索引位置:


字符串索引可以獲取字符串變量中的單個(gè)字符干毅,而字符串切片則可以讓你獲取一個(gè)連續(xù)序列的子字符串。切片的格式和用法同索引類似泼返,不過需要增加第二個(gè)索引值用來告訴Python要返回多少字符硝逢。
下面是一個(gè)切片的例子。Floodplain.shp變量值已經(jīng)賦值給theSring變量。使用theSring[0:5]語句就可以獲取一個(gè)包含Flood的變量:

theString = "Floodplain.shp"
print theString[0:5]

運(yùn)行結(jié)果如下:

Flood

Python切片返回的字符是以第一個(gè)位置開始到第二個(gè)位置結(jié)束渠鸽,但不包括第二個(gè)位置的字符叫乌。這點(diǎn)對于Python新手會感到困惑,而且也是常見的錯(cuò)誤原因徽缚。我們上面的示例中返回的變量包含Flood內(nèi)容憨奸。第一個(gè)字符是F占據(jù)位置0。最后一個(gè)字符d占據(jù)位置4猎拨。需要注意索引數(shù)5位置上的字符并沒有返回膀藐,這是因?yàn)镻ython切片僅返回到第二個(gè)位置但不包含第二個(gè)位置的字符

兩個(gè)位置值都可以忽略。這種情況下相當(dāng)于通配符的作用效果红省。theString[1:]的情況下會告訴Python要返回從第二個(gè)字符開始的所有字符额各。theString[:-1]的情況則告訴Python要返回除最后一個(gè)字符外的所有字符。
Python是處理文本的優(yōu)秀語言吧恃,它提供了許多處理字符的功能虾啦。其中大部分的功能已經(jīng)超出了本書介紹的范圍,下面列出的功能都可以實(shí)現(xiàn):

  • 字符串長度
  • 大小寫轉(zhuǎn)換
  • 去除首尾空格
  • 查找字符
  • 替換文本
  • 基于分隔符拆分字符串
  • 文本格式化

數(shù)值
Python同樣也內(nèi)置支持(built-in support)包括整型痕寓,長整型傲醉,浮點(diǎn)型和復(fù)數(shù)等數(shù)值數(shù)據(jù)。數(shù)值賦值給變量的方式跟字符基本一致呻率,只是不需要將值括在引號內(nèi)硬毕,而且該值必須是一個(gè)數(shù)值型數(shù)據(jù)。
Python支持所有常用的數(shù)值計(jì)算礼仗,包括加吐咳,減,乘元践,除以及取模(求余)等韭脊。另外Python還支持絕對值,字符型轉(zhuǎn)為數(shù)值型和四舍五入等功能单旁。
盡管Python也提供了一些內(nèi)置的數(shù)學(xué)函數(shù)沪羔,但使用math模塊可以獲取更多更高級的數(shù)學(xué)函數(shù)。使用這些函數(shù)象浑,你首先需要按照下面的方式導(dǎo)入math模塊:

import math

math模塊提供的函數(shù)包括上下取整函數(shù)蔫饰,絕對值函數(shù),三角函數(shù)融柬,對數(shù)函數(shù)死嗦,弧度轉(zhuǎn)換以及雙曲線函數(shù)等。
列表
我們介紹的第三個(gè)Python內(nèi)置數(shù)據(jù)類型是列表粒氧。列表是對象的有序集合越除,這些數(shù)據(jù)可以是Python支持的數(shù)據(jù)類型的任意一種或幾種,比如數(shù)值,字符串摘盆,其他列表翼雀,字典或?qū)ο蟮取Ee個(gè)例子來講就是一個(gè)列表對象可以同時(shí)存放數(shù)值和字符數(shù)據(jù)孩擂。列表是從零開始索引(zero-based)狼渊,也就是說列表中的第一個(gè)元素占據(jù)位置0,后面的元素位置索引依次遞增1类垦。另外狈邑,列表是可動態(tài)伸縮的。
使用方括號([ ])將一系列值括起來賦值給變量即可創(chuàng)建列表蚤认。變量名稱后面緊跟方括號括起來的一個(gè)整數(shù)值的語句格式就能夠獲取列表中的一個(gè)元素值米苹。下面的示例代碼用來說明這一過程。你還可以使用切片來返回多個(gè)元素值砰琢。使用列表切片將返回一個(gè)新的列表對象蘸嘶。

fcList = ["Hydrants", "Water Mains", "Valves", "Wells"]
fc = fcList[0]
print fc
fc = fcList[3]
print fc

運(yùn)行結(jié)果如下:

Hydrants
Wells

列表是動態(tài)可變的,可以對列表內(nèi)容進(jìn)行增加陪汽,刪除和更改训唱。完成這些操作也不需要?jiǎng)?chuàng)建一個(gè)新的備份列表對象。更改列表中元素值可以通過切片或索引操作來完成挚冤。索引操作更改一個(gè)元素值况增,而切片操作則可以更改多個(gè)列表元素值。
列表支持許多對列表中的元素值進(jìn)行操作的方法训挡。你可以使用sort()
方法來對列表內(nèi)容按照升序或降序排列巡通。你可以使用append()方法在列表末尾添加元素對象,使用insert()方法在列表中指定位置插入元素對象舍哄。你可以使用remove()方法來刪除首次出現(xiàn)在列表中的元素值,使用pop()方法則刪除最后添加到列表中的元素并返回該元素值誊锭。你還可以使用reverse()方式實(shí)現(xiàn)列表內(nèi)容的前后順序倒置表悬。
元組
元組與列表類似,但是有一些重要的區(qū)別丧靡。與列表一樣元組也是一個(gè)值的序列蟆沫。兩者的區(qū)別就是元組是不可變的,而且使用圓括號來創(chuàng)建而不是方括號温治。創(chuàng)建一個(gè)元組就是簡單地把一些用逗號分隔符隔開的值括在圓括號內(nèi)饭庞,如下面的示例代碼所示:

fcTuples = ("Hydrants","Water Mains","Valves","Wells")

同列表一樣,元組也是從0開始索引熬荆。獲取元組中的元素值的方法同列表一樣舟山。下面的示例代碼就說明了這個(gè)問題:

fcTuples = ("Hydrants","Water Mains","Valves","Wells")
print fcTuples[1]

運(yùn)行結(jié)果如下:

Water Mains

當(dāng)需要要求數(shù)據(jù)保持靜態(tài)的時(shí)候,通常使用元組來代替列表。這是因?yàn)槭褂昧斜砭筒荒鼙WC這一點(diǎn)累盗,而使用元組就可以寒矿。
字典
字典是我們介紹的第二類Python集合對象。字典跟列表類似若债,不過字典是對象的無序集合符相。不同于使用位置索引值來從集合中獲取對象,字典是使用鍵值(key)來獲取字典內(nèi)的元素值已维。字典中的每一個(gè)鍵值都有一個(gè)與之對應(yīng)的數(shù)據(jù)值昌简。與列表類似规丽,字典可以使用dictionary類中的方法實(shí)現(xiàn)字典內(nèi)容的增減操作。在下面的示例代碼中蓝牲,你將會了解到如何創(chuàng)建字典并向字典中填充數(shù)據(jù)以及如何通過鍵值來獲取值。字典是使用花括號({ })來創(chuàng)建的躏碳。在括號內(nèi)每一個(gè)鍵值是用引號括起來后面緊跟一個(gè)冒號以及對應(yīng)的數(shù)據(jù)值搞旭。字典內(nèi)的鍵值對用逗號隔開:

##創(chuàng)建字典
dictLayers = {'Roads': 0, 'Airports': 1, 'Rail': 2}
##使用鍵值獲取值
print dictLayers['Airports']
print dictLayers['Rail']

運(yùn)行結(jié)果如下:

1
2

基本的字典操作包括獲取字典內(nèi)的元素個(gè)數(shù),使用鍵值獲取數(shù)據(jù)值菇绵,判斷某個(gè)鍵值是否存在肄渗,將鍵值轉(zhuǎn)為列表對象以及獲取數(shù)據(jù)值列表。字典內(nèi)容可以更改咬最,增加以及刪除翎嫡。這也就意味著Python無需創(chuàng)建一個(gè)新的dictionary對象來保存字典的更改版本數(shù)據(jù)。給字典的鍵值賦值的操作可以通過將要賦值的鍵值擴(kuò)到方括號內(nèi)永乌,然后讓其等于某個(gè)值就可惑申。

跟列表不同,由于字典內(nèi)容是無序的所以不能使用切片操作翅雏。使用keys()方法返回字典中所有鍵值的一個(gè)集合來遍歷字典中的所有值或者也可以用來單獨(dú)獲取或者設(shè)置數(shù)據(jù)值

類和對象
類和對象是面向?qū)ο蟮木幊讨凶顬榛镜母拍钊ν铡1M管Python更傾向于是一種過程語言,但是它同樣支持面向?qū)ο缶幊掏浮T诿嫦驅(qū)ο缶幊讨屑ù啵愂怯糜趧?chuàng)建對象實(shí)例的。你可以認(rèn)為類是用于創(chuàng)建一個(gè)或多個(gè)對象的圖紙橄抹。對象實(shí)例有相同的屬性和方法靴迫,然而每個(gè)對象所包含的數(shù)據(jù)可以而且通常是不同的。對象在Python中是由屬性和方法組成的復(fù)雜的數(shù)據(jù)類型楼誓,跟其他數(shù)據(jù)類型一樣可以賦值給變量玉锌。屬性包含了與對象有關(guān)的數(shù)據(jù),而方法則是對象可以執(zhí)行的動作疟羹。
下面的示例中很好地闡釋說明了上述概念主守。在ArcPy中禀倔,Extent類是由左下角坐標(biāo)和右上角坐標(biāo)指定的一個(gè)矩形范圍。Extent類包含了許多屬性和方法丸逸。其中屬性包括XMin,XMax,YMin,YMax,spatialReference等等蹋艺。橫縱坐標(biāo)的最大和最小坐標(biāo)值(XMin,XMax,YMin,YMax)指定了矩形范圍大小。spatialReference屬性保存了Extent類中的SpaitalReference對象的參考坐標(biāo)系數(shù)據(jù)黄刚。Extent類的對象實(shí)例可以使用點(diǎn)標(biāo)注符(dot notation)來設(shè)置并獲取以上這些屬性值捎谨。示例代碼如下所示:

import arcpy
##路徑替換為本地計(jì)算機(jī)上的文件路徑
fc = "c:/ArcpyBook/data/TravisCounty/TravisCounty.shp"
## 使用游標(biāo)對象獲取每一個(gè)要素的范圍和空間參考(游標(biāo)的概念在后面會詳細(xì)介紹)
for row in arcpy.da.SearchCursor(fc, ["SHAPE@"]):
    # 獲取TravisCounty數(shù)據(jù)的范圍
    ext = row[0].extent
    # 打印四至坐標(biāo)和參考坐標(biāo)系
    print "XMin: " + str(ext.XMin)
    print "XMax: " + str(ext.XMax)
    print "YMin: " + str(ext.YMin)
    print "YMax: " + str(ext.YMax)
    print "Spatial Reference: " + ext.spatialReference.name

運(yùn)行結(jié)果如下:

XMin: 2977896.74002
XMax: 3230651.20622
YMin: 9981999.27708
YMax: 10200100.7854
Spatial Reference: NAD_1983_StatePlane_Texas_Central_FIPS_4203_Feet

Extent類有許多方法,其中大部分是驗(yàn)證Extent對象與其他幾何對象的幾何關(guān)系的方法憔维。比如有contains()涛救,crosses(),disjoint()业扒,equals()检吆,overlaps(),touches()以及within()程储。
你需要了解的另一個(gè)面向?qū)ο缶幊痰母拍钍屈c(diǎn)標(biāo)注符蹭沛。點(diǎn)標(biāo)注符(dot notation)提供了一種獲取對象屬性和方法的方式。點(diǎn)標(biāo)注符用來指明某個(gè)屬性或方法隸屬于某個(gè)特定的類章鲤。
使用點(diǎn)標(biāo)注符的語句是對象實(shí)例后面緊跟一個(gè)點(diǎn)符號(.)以及屬性或是方法名稱摊灭。獲取對象屬性和方法的語句都是一樣。如果點(diǎn)符號后面的語句末尾是圓括號括起來的零個(gè)或多個(gè)參數(shù)的話败徊,那就說明正在訪問對象的一個(gè)方法帚呼。下面的兩個(gè)例子能夠很好地說明這個(gè)問題:

屬性(Property) => extent.XMin
方法(Method) => extent.touches()

語句
你使用Python編寫的每一行代碼都稱作語句。Python中有許多類型的語句皱蹦,包括變量命名和賦值語句煤杀,基于驗(yàn)證結(jié)果執(zhí)行代碼的條件語句,用來執(zhí)行多次相同語句塊的循環(huán)語句等等沪哺。你在編寫腳本語句時(shí)需要遵循許多規(guī)則沈自。你已經(jīng)遇到過一種類型的語句:變量命名和賦值語句。
條件語句
if/elif/else語句是Python中重要的條件語句辜妓,該語句用于判斷true/false狀態(tài)酥泛。使用條件語句能夠控制程序的流程。這里舉幾個(gè)例子說明:如果變量是一個(gè)點(diǎn)要素類嫌拣,那么就獲取其X,Y坐標(biāo)值呆躲;如果要素類的名稱為Roads异逐,那么就獲取其Name字段。
if/elif/else這樣的條件語句用來判斷true/false狀態(tài)插掂。在Python中灰瞻,"true"值是指任何非零數(shù)字或非空對象腥例。"false"值是指零值或空對象,即非true值酝润。比較測試返回1或者0(true或者false),布爾與或(and/or)操作符返回true或者false燎竖。

if fcName == 'Roads':
    gp.Buffer_analysis(fc, "c:\\temp\\roads.shp", 100)
elif fcName == 'Rail':
    gp.Buffer_analysis(fc, "c:\\temp\\rail.shp", 50)
else:
    print "Can't buffer this layer"

Python代碼必須遵循一定的語法規(guī)則。代碼遇到分支語句之前要销,逐句依次執(zhí)行构回。分支語句通常在if/elif/else中實(shí)現(xiàn)。另外疏咐,使用for或者while循環(huán)語句也能更改語句的執(zhí)行順序纤掸。Python能夠自動識別語句和代碼塊的范圍,因此不需要在語句塊前后增加括號或者分隔符浑塞。實(shí)際上借跪,Python使用縮進(jìn)來組合語句塊。許多程序語言使用分號作為語句的結(jié)尾酌壕,而Python使用行結(jié)束符來標(biāo)識語句結(jié)尾掏愁。復(fù)合語句(compound statement)會包含“:”符號。復(fù)合語句遵循以下模式:頭語句(header)以冒號結(jié)束卵牍,頭語句內(nèi)的編寫的語句塊使用縮進(jìn)果港。
縮進(jìn)對Python解釋語句的方式非常重要,這里需要特別說明一下辽慕。前面內(nèi)容提過京腥,Python使用縮進(jìn)來檢測一個(gè)連續(xù)的語句部分。默認(rèn)情況下溅蛉,所有的Python語句中遇到循環(huán)語句公浪,條件語句,try/except語句和with語句前都應(yīng)該左對齊船侧。這里包括forwhile循環(huán)語句欠气,if/else語句,try/except語句和with語句镜撩。同一語句塊內(nèi)的所有語句在語句塊結(jié)束之前使用相同的縮進(jìn)预柒。
循環(huán)語句
循環(huán)語句可以讓程序根據(jù)需要來重復(fù)執(zhí)行某段代碼內(nèi)容。while循環(huán)語句中袁梗,只要循環(huán)體開始部分的條件判斷為真就會重復(fù)執(zhí)行語句塊宜鸯。當(dāng)條件判斷為假,Python則開始執(zhí)行while循環(huán)體后面的代碼遮怜。在下面的示例代碼中淋袖,將10賦值給變量x。while循環(huán)語句判斷x是否小于100锯梁,如果x小于100則將當(dāng)前x的值輸出到屏幕同時(shí)將x的值增加10即碗。語句執(zhí)行后再進(jìn)行while語句的條件判斷焰情,第二次判斷時(shí)當(dāng)前x的值為20,因此條件判斷結(jié)果仍為真剥懒。該過程直到x大于100時(shí)結(jié)束内舟。在那個(gè)時(shí)候,條件判斷結(jié)果為假初橘,循環(huán)語句執(zhí)行結(jié)束验游。這一點(diǎn)對于中止跳出while循環(huán)語句是非常重要的。否則的話壁却,你將會先入死循環(huán)中批狱。死循環(huán)就是計(jì)算機(jī)程序中的無限循環(huán)一段指令,死循環(huán)的出現(xiàn)要么是由于循環(huán)語句中無中止條件展东,或是有中止條件但從未滿足該條件赔硫,亦或是中止條件滿足后導(dǎo)致循環(huán)重新開始:

x = 10
while x < 100:
    print x
    x = x + 10

for循環(huán)語句會按照預(yù)先設(shè)定的循環(huán)次數(shù)來執(zhí)行一段語句塊。for循環(huán)有兩種情況盐肃,一種是計(jì)數(shù)循環(huán)(counted loop)爪膊,根據(jù)設(shè)定的循環(huán)次數(shù)來循環(huán)運(yùn)行一段語句塊,另一種是列表循環(huán)(list loop)砸王,允許你迭代列表中的所有對象推盛。下面的示例代碼中,列表循環(huán)中會對字典中的每一個(gè)值執(zhí)行一次代碼谦铃,然后循環(huán)結(jié)束:

dictLayers = {"Roads":"Line","Rail":"Line","Parks":"Polygon"}
lstLayers = dictLayers.keys()
for x in lstLayers:
    print dictLayers[x]

有些時(shí)候中止循環(huán)是很有必要的耘成。breakcontinue語句可用來中止循環(huán)。break語句跳出離它最近的循環(huán)體驹闰,而continue語句則是跳回到離它最近的循環(huán)體的最高層繼續(xù)下一個(gè)循環(huán)瘪菌。兩個(gè)語句可以出現(xiàn)在語句塊中任何地方。
try語句
try語句是用來處理異常的完整的復(fù)合語句嘹朗。異常是一種主要用來捕獲錯(cuò)誤或觸發(fā)錯(cuò)誤的高級控制機(jī)制师妙。Python中的異常可以捕獲或者觸發(fā)屹培。當(dāng)代碼中的發(fā)生錯(cuò)誤時(shí)默穴,Python會自動觸發(fā)異常,這些異惩市悖可以在代碼中處理或者忽略掉蓄诽。你作為程序員來決定是否捕獲自動觸發(fā)的異常。異常還可以手動觸發(fā)媒吗。在這一案例中仑氛,你將會了解到捕獲人工觸發(fā)異常的常規(guī)處理流程。
Python中的try語句有兩種基本類型:try/except/elsetry/finally蝴猪。一個(gè)基本的try語句從try語句頭開始调衰,后面緊跟著語句塊,之后為一個(gè)或多個(gè)可選的except語句自阱,這些except語句用來命名捕獲的異常嚎莉,最后是一個(gè)可選的else語句:

import arcpy
import sys
inFeatureClass = arcpy.GetParameterAsText(0)
outFeatureClass = arcpy.GetParameterAsText(1)
try:
    #如果輸入的要素類名稱已經(jīng)存在,觸發(fā)一個(gè)錯(cuò)誤
    if arcpy.Exists(inFeatureClass):
        raise overwirttenError(outFeatureClass)
    else:
        #其他處理步驟
except overwrittenError as e:
    #返回消息代碼12沛豌,同時(shí)還提供輸出要素類名稱增加到消息中
    arcpy.AddIDMessage("Error",12,str(e))

try/except/else語句工作流程如下所述趋箩。try語句開始后,Python會標(biāo)注說明現(xiàn)在已經(jīng)位于try語句塊中加派,同時(shí)也就知道當(dāng)出現(xiàn)任何異常情況時(shí)Python會將異常提交給except語句來處理叫确。如果找到了匹配異常的except語句,Python就會執(zhí)行該except語句中代碼芍锦。異常處理完成后就會開始執(zhí)行整個(gè)try語句塊后面的代碼竹勉。在這種情況下else語句則不會執(zhí)行,而try語句塊內(nèi)的語句都會執(zhí)行娄琉。如果沒有異常發(fā)生次乓,指針將會先跳到else語句執(zhí)行完else中的代碼之后再調(diào)到整個(gè)try語句塊后面的首行代碼。
另一種類型的try語句是try/finally語句孽水,該類型語句會執(zhí)行終止操作(比如關(guān)閉文件票腰,釋放等)。try語句中使用finally語句女气,無論異常情況是否發(fā)生都將會執(zhí)行finally語句塊中的代碼杏慰。
try/finally語句工作流程如下所述。異常發(fā)生時(shí)炼鞠,Python會先執(zhí)行try語句塊缘滥,之后再執(zhí)行finally語句塊,隨后繼續(xù)執(zhí)行整個(gè)try語句塊后面的代碼簇搅。如果沒有異常發(fā)生完域,Python則執(zhí)行完try語句塊后接著執(zhí)行finally語句塊。你希望無論異常是否發(fā)生都要保證某項(xiàng)操作執(zhí)行的時(shí)候瘩将,使用try/finally語句就非常有幫助吟税。比如像關(guān)閉文件或者是斷開數(shù)據(jù)庫鏈接這樣的釋放清理(cleanup)操作通常都會放到finally語句塊中,以保證無論異常是否出現(xiàn)釋放清理操作都會執(zhí)行:

import arcpy
from arcpy import env
class LicenseError(Exception):
    pass
env.workspace="E:/dem.gdb"      
try:
    if arcpy.CheckExtension("3D") == "Available":
        arcpy.CheckOutExtension("3D")
    else:
        raise LicenseError
    arcpy.HillShade_3d("N53E126","dem_hill",300)
    arcpy.Aspect_3d("N53E126","dem_aspect")

except LicenseError:
    print "3D Analyst license is unavailable"
except:
    print arcpy.GetMessages(2)
finally:
    arcpy.CheckInExtension("3D")

with語句
當(dāng)需要執(zhí)行成對出現(xiàn)的兩個(gè)關(guān)聯(lián)操作以及兩個(gè)操作中間的一段代碼的時(shí)候姿现,使用with語句就很方便肠仪。使用with語句常見的情況是文件的打開,讀取和關(guān)閉备典。文件打開和關(guān)閉是關(guān)聯(lián)操作异旧,而讀取文件以及處理文件內(nèi)容則是兩個(gè)關(guān)聯(lián)操作中間的一段代碼。使用10.1版本新引入的cursor對象來編寫ArcGIS地理處理腳本情況就很適合使用with語句提佣。我們將會在后面的章節(jié)中討論cursor對象的更多細(xì)節(jié)吮蛹,這里我就先簡單介紹一下荤崇。游標(biāo)對象是內(nèi)存中要素類或表的屬性表數(shù)據(jù)的備份。ArcGIS中提供了許多類型的游標(biāo)潮针。插入游標(biāo)用來插入新的記錄术荤,搜索游標(biāo)是只讀的記錄備份,更新游標(biāo)可以用來編輯或刪除記錄每篷。使用with語句來打開游標(biāo)瓣戚,執(zhí)行某些操作后會自動釋放游標(biāo)。
使用with語句來自動關(guān)閉文件或者游標(biāo)對象焦读,帶來更為簡潔高效的編碼體驗(yàn)子库。with語句跟try/finally語句很像,但是代碼更少矗晃。在下面的示例代碼中仑嗅,使用with語句來創(chuàng)建一個(gè)搜索游標(biāo),讀取游標(biāo)對象中的信息之后隱式地關(guān)閉游標(biāo):

import arcpy
fc = "c:/data/city.gdb/streets"
#打印每行數(shù)據(jù)的ID值并獲取幾何屬性
with arcpy.da.SearchCursor(fc,("OID@","SHAPE@AREA")) as cursor:
    for row in cursor:
        print ("Feature {0} has an area of {1}".format(row[0],row[1]))
文件讀寫(File I/O)

你會經(jīng)常需要讀寫計(jì)算機(jī)中的文件喧兄。Python包含了一個(gè)內(nèi)置的對象類型提供了獲取文件的方式无畔。盡管我們只介紹Python文件操作功能的一小部分,但這些功能都是最為常用的功能吠冤,包括文件的打開和關(guān)閉浑彰,文件的讀取和寫入等。
Python的open()函數(shù)會創(chuàng)建一個(gè)文件對象拯辙,該對象相當(dāng)于你的電腦中文件的一個(gè)鏈接郭变。你在對文件進(jìn)行讀寫數(shù)據(jù)之前必須先對該文件調(diào)用open函數(shù)。open()函數(shù)中的第一個(gè)參數(shù)是你要打開文件的路徑涯保,第二個(gè)參數(shù)對應(yīng)某個(gè)模式诉濒,通常是讀(r),寫(w)或者添加(a)夕春。r值表示你打開文件只是進(jìn)行讀取操作未荒,而w值表示你打開文件需要進(jìn)行寫入操作。打開一個(gè)已有文件進(jìn)行寫操作時(shí)及志,Python會覆蓋掉文件中已有數(shù)據(jù)片排,因此選擇寫入模式的時(shí)候需要注意。添加模式(a)將會打開文件進(jìn)行寫入操作速侈,但不會覆蓋掉任何已有數(shù)據(jù)率寡,只是將新寫入的數(shù)據(jù)添加到文件的末尾。下面的示例代碼會說明使用open函數(shù)在只讀模式下打開文件的用法:

f = open('Wildfires.txt','r')

在完成文件的讀寫操作后倚搬,你需要使用close方法來關(guān)閉文件冶共。
文件打開之后,你可以通過不同方式和方法來讀取數(shù)據(jù)。最典型的就是通過
readline()方法來一次讀取一行數(shù)據(jù)捅僵。readline()方法可以用來一次讀取文件的一行數(shù)據(jù)并賦值給一個(gè)字符型變量家卖。你就需要在Python代碼中使用循環(huán)模式來逐行讀取整個(gè)文件。如果你想一次讀取整個(gè)文件并放到一個(gè)變量中的話庙楚,你就可以使用read()方法篡九,該方法會讀取整個(gè)文件直至文件結(jié)束標(biāo)志(EOF)。你還可以使用readlines()方法來讀取整個(gè)文件醋奠,并在遇到文件結(jié)束符前按行分成各個(gè)單獨(dú)的字符串。
下面的示例代碼中伊佃,我們以只讀模式打開一個(gè)Wildfires.txt的文件窜司,并調(diào)用readlines()方法將文件的整個(gè)內(nèi)容讀取到lstFires變量中去lstFires變量是一個(gè)Python列表,文件的每行內(nèi)容都是該列表中的一個(gè)字符串元素值航揉。在本案例中塞祈,Wildfires.txt是一個(gè)逗號分隔符的文本文件,該文件中包含了每次火情的經(jīng)緯度位置以及可信度數(shù)據(jù)帅涂。我們將迭代讀取lstFires中的每行文本议薪,調(diào)用split()函數(shù)按照逗號分隔符來分別提取緯度,經(jīng)度和可信度數(shù)據(jù)媳友。經(jīng)緯度值用于創(chuàng)建一個(gè)新Point對象斯议,該對象將會使用插入游標(biāo)插入到要素類中:

import arcpy,os
try:    
    #打開要讀取的文件
    f = open('Wildfires.txt','r')
    lstFires = f.readlines()
    cur = arcpy.InsertCursor("e:/dem.gdb/FireIncidents")
    for fire in lstFires:
        if 'Latitude' in fire:
            continue       
        vals = fire.split(",")        
        latitude = float(vals[0])
        longtitude = float(vals[1])
        confid = int(vals[2])
        print(longtitude,latitude)
        pnt = arcpy.Point(longtitude,latitude)
        feat = cur.newRow()
        feat.shape = pnt
        feat.setValue("CONFIDENCEVALUE",confid)
        cur.insertRow(feat)
    del feat
    del cur
except:
    print arcpy.GetMessages()
finally:    
    f.close()

正如讀取文件的情況一樣,你可以使用一些方法來把數(shù)據(jù)寫入文件中醇锚。write()方法大概是最方便的哼御,該方法引用一個(gè)字符串參數(shù)然后把該參數(shù)值寫入到文件中。wirtelines()方法可用于將列表結(jié)構(gòu)的內(nèi)容寫入到文件中焊唬。在下面的示例代碼中恋昼,我們創(chuàng)建了一個(gè)fcList的列表,該列表中包含了一些要素類名稱赶促。我們可以調(diào)用writelines()方法將列表內(nèi)容寫入到文件中:

outfile = open('c:\\temp\\data.txt','w')
fcList = ["Strams","Roads","Counties"]
outfile.writelines(fcList)
outfile.close()

總結(jié)

我們介紹了一些基本的Python語言編程的概念液肌,這些概念是你編寫地理處理腳本之前需要事先了解的。本章內(nèi)容我們首先介紹了用于編寫和調(diào)試代碼的IDLE開發(fā)環(huán)境的情況鸥滨。你了解到如何創(chuàng)建一個(gè)新的腳本嗦哆,如何編輯一個(gè)現(xiàn)有的腳本文件以及如何檢查語法錯(cuò)誤和執(zhí)行腳本。我們還介紹了基本的編程語言結(jié)構(gòu)爵赵,比如模塊導(dǎo)入吝秕,變量創(chuàng)建和賦值,if/else條件語句空幻,循環(huán)語句以及不同的數(shù)據(jù)類型烁峭,其中包括字符,數(shù)值,布爾约郁,列表缩挑,字典和對象,你還了解到如何讀寫文本文件鬓梅。
在下一部分中供置,你還會了解到在ArcGIS中使用Python編寫地理處理腳本的基本技巧。你還會了解到如何使用ArcGIS桌面軟件中內(nèi)置的Python窗口绽快,如何在腳本中導(dǎo)入ArcPy包芥丧,如何在腳本中執(zhí)行ArcToolbox工具,如何在腳本編寫中利用幫助系統(tǒng)坊罢,如何使用變量保存數(shù)據(jù)以及如何訪問各種ArcPy模塊续担。


前言 ||| 第二章 使用ArcPy編寫腳本

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市活孩,隨后出現(xiàn)的幾起案子物遇,更是在濱河造成了極大的恐慌,老刑警劉巖憾儒,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件民珍,死亡現(xiàn)場離奇詭異饼酿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門梨州,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嘶炭,“玉大人洽腺,你說我怎么就攤上這事武福。” “怎么了缭保?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵汛闸,是天一觀的道長。 經(jīng)常有香客問我艺骂,道長诸老,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任钳恕,我火速辦了婚禮别伏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忧额。我一直安慰自己厘肮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布睦番。 她就那樣靜靜地躺著类茂,像睡著了一般耍属。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巩检,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天厚骗,我揣著相機(jī)與錄音,去河邊找鬼兢哭。 笑死领舰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迟螺。 我是一名探鬼主播冲秽,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矩父!你這毒婦竟也來了劳跃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤浙垫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后郑诺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夹姥,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年辙诞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辙售。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡飞涂,死狀恐怖旦部,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情较店,我是刑警寧澤士八,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站梁呈,受9級特大地震影響婚度,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜官卡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一蝗茁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寻咒,春花似錦哮翘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春佩研,著一層夾襖步出監(jiān)牢的瞬間柑肴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工旬薯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晰骑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓绊序,卻偏偏與公主長得像硕舆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子骤公,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容