day10-內置模塊學習(一)

今日份目錄node

1.模塊之間的相互調用python

2.代碼結構的標準化mysql

3.os模塊git

4.sys模塊github

5.collection模塊redis

 

開始今日份總結sql

開始今日份總結shell

1.模塊之間的相互調用bash

因爲一些緣由,老是會調用別人的模塊以及接口包括其餘亂七八糟的東西,這個時候就須要了模塊之間的相互調用。app

引用模塊至關於執行這個模塊,不太重新導入會直接引用內存中已經加載好的結果。

模塊被執行時發生了三件事:

  1. 建立一個以被導入模塊的名字命名的名稱空間
  2. 自動執行模塊中的代碼(將模塊中的全部內容加載到內存)
  3. 要想執行模塊中的代碼必須經過模塊名.的方式執行獲取

1.1 模塊的更名

#   1,模塊名過長,引用不方便,給模塊更名,簡化引用。
import abcdpythonuser as ab
print(ab.age)
ab.func()
import time
print(time.time())
import time as t
print(t.time())
#   2, 優化代碼。
import mysql
import orcle
db_sql = input('>>> ')
if db_sql == 'mysql':
    mysql.sqlparse()
elif db_sql == 'orcle':
    orcle.sqlparse()

改版
db_sql = input('>>> ')
if db_sql == 'mysql':
    import mysql as db
elif db_sql == 'orcle':
    import orcle as db
db.sqlparse()

1.2多個模塊的引用

標準的:
import mysql
import time
import sys
不建議:
import mysql,time,os,sys

1.3其餘引用

# from ..... import .....
# 執行過程:
'''
1,執行一遍tbjx的全部代碼,加載到內存。
2,將name,read1這些實際引用過來的變量函數在本文件複製一份。
    globals()查看
'''
from tbjx import name,read1
print(name)
read1()
# 好處:使用簡單。
# 壞處:容易與本文件的變量,函數名等發生衝突。

多個導入的時候

#導入多個:
# 方式一
from tbjx import name
from tbjx import raed1
# 方式2
from tbjx import name,read1,read2

# 導入全部:
from tbjx import *
print(globals())
# 通常不用,
# 若是使用只有兩點:
    # 1,將導入的模塊中的全部的代碼所有清楚的前提下,可使用 *。
from time import time
    # 2,只是用一部分。

文件有個兩個做用:

  • 做爲腳本,直接運行
  • 做爲模塊供別人使用。
  • __name__ == '__main__' 能夠做爲一個項目的啓動文件用。

2.代碼結構的標準化

2.1爲何設計項目目錄結構

"設計項目目錄結構",就和"代碼編碼風格"同樣,屬於我的風格問題。對於這種風格上的規範,一直都存在兩種態度:

  1. 一類同窗認爲,這種我的風格問題"可有可無"。理由是能讓程序work就好,風格問題根本不是問題。
  2. 另外一類同窗認爲,規範化能更好的控制程序結構,讓程序具備更高的可讀性。

我是比較偏向於後者的,由於我是前一類同窗思想行爲下的直接受害者。我曾經維護過一個很是很差讀的項目,其實現的邏輯並不複雜,可是卻耗費了我很是長的時間去理解它想表達的意思。今後我我的對於提升項目可讀性、可維護性的要求就很高了。"項目目錄結構"其實也是屬於"可讀性和可維護性"的範疇,咱們設計一個層次清晰的目錄結構,就是爲了達到如下兩點:

  1. 可讀性高: 不熟悉這個項目的代碼的人,一眼就能看懂目錄結構,知道程序啓動腳本是哪一個,測試目錄在哪兒,配置文件在哪兒等等。從而很是快速的瞭解這個項目。
  2. 可維護性高: 定義好組織規則後,維護者就能很明確地知道,新增的哪一個文件和代碼應該放在什麼目錄之下。這個好處是,隨着時間的推移,代碼/配置的規模增長,項目結構不會混亂,仍然可以組織良好。

因此,我認爲,保持一個層次清晰的目錄結構是有必要的。更況且組織一個良好的工程目錄,實際上是一件很簡單的事兒。

2.2推薦的目錄結構

988316-20181121163718442-1480089123

2.3 關於read me

這個我以爲是每一個項目都應該有的一個文件,目的是能簡要描述該項目的信息,讓讀者快速瞭解這個項目。

它須要說明如下幾個事項:

  1. 軟件定位,軟件的基本功能。
  2. 運行代碼的方法: 安裝環境、啓動命令等。
  3. 簡要的使用說明。
  4. 代碼目錄結構說明,更詳細點能夠說明軟件的基本原理。
  5. 常見問題說明。

我以爲有以上幾點是比較好的一個README。在軟件開發初期,因爲開發過程當中以上內容可能不明確或者發生變化,並非必定要在一開始就將全部信息都補全。可是在項目完結的時候,是須要撰寫這樣的一個文檔的。

能夠參考Redis源碼中Readme的寫法,這裏面簡潔可是清晰的描述了Redis功能和源碼結構。

3.os模塊

od模塊是整個代碼過程當中常常要使用的一個模塊

#當前執行這個python文件的工做目錄相關的工做路徑
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ('.')
os.pardir  獲取當前目錄的父目錄字符串名:('..')

#和文件夾相關
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印

# 和文件相關
os.remove()  刪除一個文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息

# 和操做系統差別相關
os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串 win下爲;,Linux下爲:
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'

# 和執行系統命令相關
os.system("bash command")  運行shell命令,直接顯示
os.popen("bash command).read()  運行shell命令,獲取執行結果
os.environ  獲取系統環境變量

#path系列,和路徑相關
os.path.abspath(path) 返回path規範化的絕對路徑 
os.path.split(path) 將path分割成目錄和文件名二元組返回 
os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 
os.path.basename(path) 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值,即os.path.split(path)的第二個元素。
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path)  若是path是絕對路徑,返回True
os.path.isfile(path)  若是path是一個存在的文件,返回True。不然返回False
os.path.isdir(path)  若是path是一個存在的目錄,則返回True。不然返回False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後訪問時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間
os.path.getsize(path) 返回path的大小

注意:os.stat('path/filename') 獲取文件/目錄信息 的結構說明

stat 結構:

st_mode: inode 保護模式
st_ino: inode 節點號。
st_dev: inode 駐留的設備。
st_nlink: inode 的連接數。
st_uid: 全部者的用戶ID。
st_gid: 全部者的組ID。
st_size: 普通文件以字節爲單位的大小;包含等待某些特殊文件的數據。
st_atime: 上次訪問的時間。
st_mtime: 最後一次修改的時間。
st_ctime: 由操做系統報告的"ctime"。在某些系統上(如Unix)是最新的元數據更改的時間,在其它系統上(如Windows)是建立時間(詳細信息參見平臺的文檔)。

stat結構

4.sys模塊

sys.argv           命令行參數List,第一個元素是程序自己路徑
sys.exit(n)        退出程序,正常退出時exit(0),錯誤退出sys.exit(1)
sys.version        獲取Python解釋程序的版本信息
sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform       返回操做系統平臺名稱

5.collection模塊

在內置數據類型(dict、list、set、tuple)的基礎上,collections模塊還提供了幾個額外的數據類型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

1.namedtuple: 生成可使用名字來訪問元素內容的tuple

2.deque: 雙端隊列,能夠快速的從另一側追加和推出對象

3.Counter: 計數器,主要用來計數

4.OrderedDict: 有序字典

5.defaultdict: 帶有默認值的字典

namedtuple

咱們知道tuple能夠表示不變集合,例如,一個點的二維座標就能夠表示成:

>>> p = (1, 2)

可是,看到(1, 2),很難看出這個tuple是用來表示一個座標的。

這時,namedtuple就派上了用場:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
>>> p.y

相似的,若是要用座標和半徑表示一個圓,也能夠用namedtuple定義:

#namedtuple('名稱', [屬性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])

deque

使用list存儲數據時,按索引訪問元素很快,可是插入和刪除元素就很慢了,由於list是線性存儲,數據量大的時候,插入和刪除效率很低。

deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧:

>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])

deque除了實現list的append()pop()外,還支持appendleft()popleft(),這樣就能夠很是高效地往頭部添加或刪除元素。

ordereddict

使用dict時,Key是無序的。在對dict作迭代時,咱們沒法肯定Key的順序。

若是要保持Key的順序,能夠用OrderedDict

>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是無序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])

注意,OrderedDict的Key會按照插入的順序排列,不是Key自己排序:

>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的順序返回
['z', 'y', 'x']

defaultdict

有以下值集合 [11,22,33,44,55,66,77,88,99,90...],將全部大於 66 的值保存至字典的第一個key中,將小於 66 的值保存至第二個key的值中。

即: {'k1': 大於66 , 'k2': 小於66}

li = [11,22,33,44,55,77,88,99,90]
result = {}
for row in li:
    if row > 66:
        if 'key1' not in result:
            result['key1'] = []
        result['key1'].append(row)
    else:
        if 'key2' not in result:
            result['key2'] = []
        result['key2'].append(row)
print(result)

原生字典的解決方法

from collections import defaultdict

values = [11, 22, 33,44,55,66,77,88,99,90]

my_dict = defaultdict(list)

for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)

defaultdict字典解決方法

使用dict時,若是引用的Key不存在,就會拋出KeyError。若是但願key不存在時,返回一個默認值,就能夠用defaultdict

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默認值
'N/A'

counter

Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素做爲key,其計數做爲value。計數值能夠是任意的Interger(包括0和負數)。Counter類和其餘語言的bags或multisets很類似。

c = Counter('abcdeabcdabcaba')
print c
輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
相關文章
相關標籤/搜索