模块
在python中,一个.py文件就称之为一个模块(Module)
大大提高了代码的可维护性
编写代码不必从零开始,当一个模块编写完毕,就可以被其他地方引用
一、自定义模块
自定义模块名字尽量不要与内置函数名字冲突,python中所有内置函数:https://docs.python.org/3/library/functions.html
[root@python code6]# vim myModule.py
#/usr/bin/env python
# coding:utf-8
def hello(): #定义一个简单函数hello
print "hello"
def login(): #定义一个简单函数login
print "login"
[root@python code6]# ipython
...
In [1]: import myModule #调用刚才写的myModile模块(即myModule.py脚本)
In [2]: myModule.hello() #使用myModule中的函数方法,会输出在myModule.py脚本中定义的内容
hello
In [3]: myModule.login()
login
[root@python code6]# ls #可以在当前脚本目录下查看,发现在ipytjon调用模块之后生成了myModule.pyc这个文件
myModule.py myModule.pyc
二、内置模块
介绍一些常用的模块,使用模块的时候需要事先声明调用的模块,即import 模块名,例如import os等
-
os模块
对操作系统进行操作
提供了对平台模块的封装(对windows、mac的封装等)
os.environ
用于获取和设置系统环境变量的内置值
#获取系统环境变量
os.environ['环境变量名称']
In [25]: import os
In [26]: os.environ['PATH']
Out[26]: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin'
注:使用模块的时候需要事先声明调用的模块,即import +模块名,例如import os等,后面内容在截图时不再声明
#设置系统环境变量
os.environ['环境变量名称']='环境变量值' #其中key和value均为string类型
In [47]: os.environ['PATH'] += ':d:/python/下载'
os.name
显示当前所在操作系统是什么(linux-"posix",windows-"nt")
In [14]: os.name
Out[14]: 'posix'
os.listdir()
返回指定的路径下包含的文件或目录的名字所组成的列表。这个列表以字母顺序。 它不包括 '.' 和'..' 即使它在文件夹中,但包含‘.’开头的隐藏文件
In [34]: os.listdir(".") #“.”表示当前路径
Out[34]:
['check_bool.py',
'function.py',
'test.py',
'myModule.py',
'myModule.pyc',
'vas']
In [35]: os.listdir("/home")
Out[35]: ['centos01', 'auth', 'code', 'tools']
os.getcwd()
获取当前的工作目录的绝对路径
In [22]: os.getcwd()
Out[22]: '/home/code/python'
练习1:
列出当前目录下所有以.py结尾的目录和文件,并加上当前工作目录的绝对路径
注:endswith()为字符串的常用操作,判断字符串是否以指定的内容结尾
In [31]: [os.getcwd()+"/"+i for i in os.listdir(".") if i.endswith(".py") ]
Out[31]:
['/home/code/python/check_bool.py',
'/home/code/python/function.py',
'/home/code/python/test.py',
'/home/code/python/myModule.py']
os.access(path,mode)
判断是否具有指定的权限,返回True或者False
path参数--要用来检测是否有访问权限的路径
mode参数--可选值:os.F_OK(是否存在),os.R_OK(读),os.W_OK(写),os.X_OK(执行)
os.stat(path)
获取path指定的路径的信息,相当于linux下的stat命令
os.mkdir(path)
创建一个名为path的目录os.mkdirs(path)
创建目录树,相当于mkdir -p 操作
os.rmdir(path)
删除指定目录
os.system()
使用python执行linux命令
In [41]: os.system("ls")
check_bool.py myModule.py test.py
function.py myModule.pyc vas
Out[41]: 0
In [42]: a=os.system("ls")
check_bool.py myModule.py test.py
function.py myModule.pyc vas
In [43]: a
Out[43]: 0
#但是如果有错误输出,返回值就不是0了
In [44]: b=os.system("lss")
sh: lss: command not found
In [45]: b
Out[45]: 32512
os.popen()
返回一个文件对象
In [55]: os.popen("ls")
Out[55]: <open file 'ls', mode 'r' at 0x7fdff3a784b0>
In [56]: f=os.popen("ls")
In [57]: f.read()
Out[57]: 'check_bool.py\nfunction.py\nmyModule.py\nmyModule.pyc\ntest.py\nvas\n'
In [58]: f.read()
Out[58]: ''
os.popen2
返回两个文件对象,一个是 stdin, 一个是 stdoutos.popen3
返回三个文件对象 :stdin,stdout,stderr
-
os.path模块
os.path 是os 的一个子模块 , 主要是对路径进行解析、创建、测试和其他的一些操作,封装了不同平台的路径操作
path.sep
路径解析,自动获取不同操作系统的目录分隔符,如linux是"/",window是"\"
练习:列出当前目录下所有文件、目录的绝对路径
In [60]: [os.getcwd()+os.path.sep+i for i in os.listdir(".")] #path.os前面还要带上os,因为它还是属于os模块
Out[60]:
['/home/code/python/check_bool.py',
'/home/code/python/function.py',
'/home/code/python/test.py',
'/home/code/python/myModule.py',
'/home/code/python/myModule.pyc',
'/home/code/python/vas']
path.split('/tmp/test/ab')
把路径分割成 dirname 和 basename,返回一个元组path.basename('/tmp/test/ab')
返回文件名path.dirname('/tmp/test/ab')
返回目录名path.join('a','b','c')
以/连接元素使之成为一个路径
In [40]: os.path.join('a','b','c')
Out[40]: 'a/b/c'
path.abspath('.')
返回绝对路径
[root@centos01 mnt]# pwd
/mnt
[root@centos01 mnt]# ls
Pictures
[root@centos01 mnt]# ipython
In [3]: import os
In [4]: os.path.abspath('mimimi.txt')
Out[4]: '/mnt/mimimi.txt' #这里返回的'绝对路径'只是把当前路径+文件名强行拼接而已,并且也不验证mimimi.txt文件是否存在
path.splitext('aaa.tar.gz')
分割路径,返回路径名和文件扩展名的元组文件属性相关:os.path.getatime ('filename')
返回最近访问时间(浮点型秒数)os.path.getctime ('filename')
返回文件 path 创建时间os.path.getmtime ('filename')
返回最近文件修改时间os.path.getsize('filename')
返回文件大小,如果文件不存在就返回错误文件测试相关:os.path.isabs(path)
判断是否为绝对路径os.path.isdir(path)
判断路径是否为目录os.path.isfile(path)
判断路径是否为文件os.path.islink(path)
判断路径是否为链接
-
random模块
random.randint(1,100)
随机生成1-100之间的一个整数
In [61]: import random
In [62]: random.randint(1,100)
Out[62]: 68
注:使用模块的时候需要事先声明调用的模块,即import +模块名,例如import os等,后面内容在截图时不再声明
random.sample("abcd",2)
从"abcd"里面随机拿出2个字母
In [71]: random.sample("abcd",2)
Out[71]: ['b', 'c']
random.sample(["hello1","hello2","hello3"],2)
从列表里面随机拿出2个元素
In [70]: random.sample(["hello1","hello2","hello3"],2)
Out[70]: ['hello1', 'hello3']
-
sys模块
sys模块主要提供了系统相关的配置和操作,封装了探测、改变解释器runtime以及资源的交互
sys.version
得到解释器的版本信息sys.platform
得到当前运行平台
sys.aegv
在外部向程序内部传递参数,参数解析类似于bash 的方式,第一个参数代表脚本本身,sys.aegv返回的是列表,因此可以使用列表的一些方法
[root@centos01 python]# vim sys_argv.py
import sys
print sys.argv
[root@centos01 python]# python sys_argv.py #返回脚本名称本身
['sys_argv.py']
[root@centos01 python]# python sys_argv.py 1
['sys_argv.py', '1']
sys.stderr , sys.stdin , sys.stdout
这些都分别代表一个文件对象
sys.path
In [7]: sys.path #查看目前所有模块匹配路径
Out[7]:
['',
'/usr/bin',
'/usr/lib64/python27.zip',
'/usr/lib64/python2.7',
'/usr/lib64/python2.7/plat-linux2',
'/usr/lib64/python2.7/lib-tk',
'/usr/lib64/python2.7/lib-old',
'/usr/lib64/python2.7/lib-dynload',
'/usr/lib64/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages/gtk-2.0',
'/usr/lib/python2.7/site-packages',
'/usr/lib/python2.7/site-packages/IPython/extensions',
'/root/.ipython']
默然情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话, 程序就会报错。所以我们一般自己写程序的话,最好把自己的模块路径给加到模块扫描的路径里,eg: sys.path.append('你的模块的路径'),这样程序就不会因为找不到模块而报错,也可以使用sys.path.insert(0,"你的模块路径")将你的模块放到最前面,作用是可以在你的模块名和其他模块名一样的情况下优先使你的模块起作用
[root@centos01 python]# pwd
/home/code/python
[root@centos01 python]# vim happy.py #定义一个happy模块
[root@centos01 python]# cd #退出happy模块所在的路径
[root@centos01 ~]# ipython #进入ipython解释器
In [1]: import sys
In [2]: sys.path.append("/home/code/python") #将/home/code/python加到模块默认寻找路径中
In [3]: import happy #可以看到当前在/root路径下,并不在happy模块所在路径下,也可以调用happy模块
In [5]: happy.hello()
hello
In [6]: sys.path.pop() #删除刚才加的模块
Out[6]: '/home/code/python'
-
time模块
python中表示时间的三种方式: In [2]: time.time() 2. 格式化的时间字符串 3. 元组(共9个元素) In [5]: time.localtime() |
time.mktime(t)
将元组格式时间转化为时间戳time.localtime()
将时间戳转化为元组格式时间
In [12]: a=time.localtime()
In [13]: a.tm_year #年
Out[13]: 2018
In [14]: a.tm_mon #月
Out[14]: 1
In [15]: a.tm_mday #日
Out[15]: 19
time.sleep(secs)
函数推迟调用线程的运行,可通过参数secs指秒数,表示进程挂起的时间time.ctime([secs])
将时间戳转化为字符串格式显示
In [6]: import time
In [7]: time.time()
Out[7]: 1516373880.876073
In [8]: time.ctime(1516373880.876073)
Out[8]: 'Fri Jan 19 22:58:00 2018'
time.strftime(format[,t])
将元组格式时间转化为字符串显示
In [17]: time.strftime("%H:%M:%S")
Out[17]: '23:04:26'
In [18]: time.strftime("%T")
Out[18]: '23:04:37'
time.strptime(string[,format])
将字符串显示转化为元组格式时间
In [19]: time.strptime("16:04:08","%X")
Out[19]: time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=16, tm_min=4, tm_sec=8, tm_wday=0, tm_yday=1, tm_isdst=-1)
time.strftime("%Y-%m-%d %X", time.localtime())
In [11]: time.strftime("%Y-%m-%d %X", time.localtime())
Out[11]: '2019-06-21 06:56:34'
time.strptime('2017-07-16 07:28:49','%Y-%m-%d %X')
In [12]: time.strptime('2017-07-16 07:28:49','%Y-%m-%d %X')
Out[12]: time.struct_time(tm_year=2017, tm_mon=7, tm_mday=16, tm_hour=7, tm_min=28, tm_sec=49, tm_wday=6, tm_yday=197, tm_isdst=-1)
练习1:
如果用户输入的参数>=2个,在当前目录创建目录hello1和hello2,并打印出这两个文件的绝对路径;如果参数=1, 显示当前目录下的所有文件;如果无任何参数, 显示当前目录下的所有目录信息(同linux的stat)
#!/usr/bin/env python
# coding:utf-8
import sys,os
argv_len=len(sys.argv)
if argv_len >= 3: #sys.argv获取的第一个参数为脚本本身,所以这里是>=3表示脚本后面跟的参数>=2个
os.mkdir("hello1")
os.mkdir("hello2")
print os.getcwd()+os.path.sep+"hello1" #当前目录绝对路径+分隔符+hello1
print os.getcwd()+os.path.sep+"hello2"
elif argv_len == 2:
all_file=[i for i in os.listdir(".") if os.path.isfile(i)] #all_file存的是当前路径下所有文件
for i in all_file:
print i
else:
all_dir=[i for i in os.listdir(".") if os.path.isdir(i)] #all_dir存的是当前路径下所有文件夹
for i in all_dir:
print os.stat(i)
练习2:
生成一个包含4个字符的随机验证码
#!/usr/bin/env python
# coding:utf-8
#describe:实测最多只能生成一个94位的随机数
import string,random,sys
length=int(sys.argv[1]) #sys.argv[1]表示脚本后面跟的第1个参数,ps:sys.argv[0]表示脚本本身
def GnePasswd(x):
all_str=string.letters+string.digits+string.punctuation #string.letters生成所有字母(包括大写和小写),string.digits生成所有数字,string.punctuation生成特殊字符,三个加起来一共有96个字符
str=random.sample(all_str,x) #random.sample(str,sep)表示从str字符串中取出sep个字符
return "".join(str) #"".join(sep)表示以""为分隔符,将序列seq中的所有元素合并为一个新的字符串
print GnePasswd(length)
执行结果:
[root@centos01 python]# python test.py 4
\<Sn
三、第三方模块
pycharm添加第三方模块:点击右上角的齿轮添加模块
pip安装第三方模块:pip install 第三方模块名
[root@python ~]# pip install itchat #使用pip安装微信的itchat第三方模块
#############################continue...###################################################
...
四、使用技巧
导入模块(加载模块的内容)
import 模块名1,模块名2,…
一行导入多个模块
import 模块名 as 模块别名
In [1]: import random as myrandom
In [2]: random.randint(1,10) #现在使用random不生效
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-30911966a1fe> in <module>()
----> 1 random.randint(1,10)
NameError: name 'random' is not defined
In [3]: myrandom.randint(1,10) #使用别名myrandom才生效
Out[3]: 4
from 模块名 import 变量或者函数
使用import导入的模块,在调用其函数的时候要先写模块名,再跟上具体使用的函数,如:
In [1]: import os
In [2]: os.getcwd()
Out[2]: '/home/code/python'
使用from...import...导入的模块,在调用其函数的时候只需指定函数名称,如:
In [1]: from os import getcwd
In [2]: getcwd() #由于只导入了os模块中的getcwd函数,因此无法使用其他函数。如listdir(".")等,即使使用全称os.listdir(".")也不行,会提示os模块未定义
Out[2]: '/home/code/python'
其他:
a.重命名
from 模块名 import 名字 as 变量
b. 导入多个
from 模块名 import 名字1,名字2..
c.from 模块 import * 导入该模块的所有内容
__all__属性
python模块中的__all__属性,可用于模块导入时限制,如:from module import *,此时被导入模块若定义了__all__属性,则只有__all__内指定的属性、方法、类可被导入。若没定义,则导入模块内的所有公有属性,方法和类
写一个模块:
[root@centos01 python]# cat myModule.py
print("demo")
a = 7
def method():
print("method run ")
__all__=['a'] #表示只有a这个函数可以被from...import *导入,如果允许多个用逗号分隔。实际测试如果使用import+模块名导入则不受此限制
在ipython中执行测试:
In [1]: from myModule import *
demo
In [2]: a
Out[2]: 7
In [3]: method()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-1ad255c02293> in <module>()
----> 1 method()
NameError: name 'method' is not defined
#实际测试使用from myModule import method依然可以将method函数导入,可见__all__是相对于from...import *而言的
from __future__ import division
__future__模块可以在旧版本中体验新版本的特性,例如下面例子:
在Python 2.x中,对于除法有两种情况,如果是整数相除,结果仍是整数,余数会被扔掉,这种除法叫“地板除”:
In [1]: 10/3
Out[1]: 3
要做精确除法,必须把其中一个数变成浮点数:
In [2]: 10.0/3
Out[2]: 3.3333333333333335
而在Python 3.x中,所有的除法都是精确除法,地板除用//
表示
如果你想在Python 2.7的代码中直接使用Python 3.x的除法,可以通过__future__
模块的division
实现:
In [4]: from __future__ import division
In [5]: 10/3
Out[5]: 3.3333333333333335
In [6]: 10.0/3
Out[6]: 3.3333333333333335
In [7]: 10//3
Out[7]: 3
摘自:https://www.liaoxuefeng.com/wiki/897692888725344/923030465280480
from __future__ import print_function
python2.X中print不需要括号,而在python3.X中则需要。
在开头加上from __future__ import print_function
这句之后,即使在python2.X,使用print也得像python3.X那样加括号使用,否则报错。
In [1]: print "Bad Apple"
Bad Apple
In [2]: print ("Bad Apple")
Bad Apple
In [3]: from __future__ import print_function
In [4]: print "Bad Apple"
File "<ipython-input-4-ae8bc87f7dea>", line 1
print "Bad Apple"
^
SyntaxError: invalid syntax
In [5]: print ("Bad Apple")
Bad Apple
__name__
#在python中,所有以“__”包起来的方法都统称为“Magic Method”,中文称魔术方法
__name__是python文件中自带的一个状态
一个python文件有两种使用方法,1.被当成脚本直接执行,2.作为模块被调用,因此:
当这个python文件直接运行时,__name__的值为__main__(__main__代表python文件名+.py后缀)
当是import导入时,__name__的值为python文件名(不带.py)因此在写代码时,会添加下面的内容,使用if语句判断,如果是作为脚本直接执行就被允许,否则不执行if下面的代码:
if __name__ == "__main__":
代码
参考:https://blog.csdn.net/zhusongziye/article/details/79505803
模块的作用域
模块中正常的函数和变量名是公共的如果想变成私有的,在前面添加"_"
在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。
正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如__author__,__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
之所以我们说,private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。
private函数或变量不应该被别人引用,那它们有什么用呢?请看例子:
def _private_1(name):
return 'Hello, %s' % name
def _private_2(name):
return 'Hi, %s' % name
def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)
我们在模块里公开greeting()函数,而把内部逻辑用private函数隐藏起来了,这样,调用greeting()函数不用关心内部的private函数细节,这也是一种非常有用的代码封装和抽象的方法,即:
外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。
摘自:https://blog.csdn.net/Pinkmanabcd/article/details/93157617