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})
相关文章
相关标签/搜索