模块:

(一个.py文件就是一个模块module,模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能。)

模块分三种: 1.python标准库 2.第三方模块 3.应用程序自定义模块

下面,先重点讲第三个,应用程序自定义模块

 在同一个python package包里面建立两个python file(如,cal.py  test.py)

 在cal.py文件里:
print('ok')
def add(x,y):
return x+y
def sub(x,y):
return x-y
print('ojbk') 在test.py文件里:
import cal
print(cal.add(3,5)) #非得加cal.
print(cal.sub(6,4)) #非得加cal.
#结果:ok ojbk 8 2
(这个执行,会先执行cal.py文件的,cal.py文件全部执行一遍才会执行test.py文件) 如果不想加cal.可以:
from cal import add
from cal import sub
print(add(3,5))
print(sub(6,4))
用from 这样就不需要加cal. from cal import add
from cal import sub
可以将其用from cal import * 代替;*星号就代表所有 #但是不推荐使用 这个import导入的模块会做三件事:
#import模块做了三件事,1:执行对应文件 2.引入变量名cal 想导入多个模块可以在模块名后面加逗号隔开,如:import cal,time

关于,import路径问题:

 import sys
print(sys.path)
#['C:\\Users\\zy\\PycharmProjects\\python全站-s3\\day20\\module_lesson'......]
#这就是import最主要的路径 当我们给module_lesson这一级再建一个package包,my_module,将cal.py文件放入,cal.py文件与test.py文件不在同一个包里面,而与my_module同级,可以:
from my_module import cal    

关于,包 package(组织模块):

 关于包的调用,与模块的调用一样,from import
(假如是三层,web,web1,web2,在web2里面调用它的cal.py文件)
方法一:from web.web1.web2 import cal
print(cal.add(2,6))
方法二:from web.web1.web2.cal import add
print(add(2,6))
#from web.web1 import web2(执行web3的__init__文件,唯一不支持的调用方式)

关于,__name__

 在执行文件里写;
print(__name__)
#结果:__main__ 在被调用文件里写;
print(__name__)
#结果:被调用文件的路径 if __name__=="__main__":
有两个作用:
【1】在被调用文件里面,它后面文件不会被调用执行,用于被调用文件的测试
【2】在执行文件里面,不想执行文件被其它文件调用

下面介绍,python标准库:

【1】时间模块:

 import time
time.sleep(2)
print('ok')
#结果:ok (会停顿两秒,再出现ok) 时间戳
import time
print(time.time())
#结果:1535856591.4900608(从1976年开始到现在为止经历了多少秒数) 结构化时间
import time
print(time.localtime())
t=time.localtime()
print(t.tm_year)
print(t.tm_wday)
#结果:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=2, #tm_hour=10, tm_min=53, tm_sec=58, tm_wday=6, tm_yday=245, #tm_isdst=0)
#
# 字符串时间 将结构化时间转换成时间戳
import time
print(time.mktime(time.localtime()))
#结果:1535857837.0 将结构化时间转换成字符串时间
import time
print(time.strftime('%Y-%m-%d %X',time.localtime()))
#结果:2018-09-02 11:15:40
(%Y-%m-%d表示年月日; %X表示时分秒;逗号后面是结构化时间) 将字符串时间转化成结构化时间
import time
print(time.strptime('2018:09:02:11:29:12','%Y:%m:%d:%X'))
#结果:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=2, #tm_hour=11, tm_min=29, tm_sec=12, tm_wday=6, tm_yday=245, #tm_isdst=-1) 把一个表示时间的元组或者struct_time表示为以下这种形式
import time
print(time.asctime())
#结果:Sun Sep 2 11:32:59 2018 另外一种时间表示形式
import datetime
print(datetime.datetime.now())
#结果:2018-09-02 11:41:09.032006

【2】random模块:

 import random
ret=random.random()
print(ret) #0-1之间的随机数
ret1=random.randint(1,3)
print(ret1)
ret2=random.randrange(1,3) #左取右不取
print(ret2)
ret3=random.choice([11,22,33])
print(ret3)
ret4=random.sample([11,22,33],2) #在列表中任意取两个
print(ret4)
ret5=random.uniform(1,3) #取1-3之间的浮点数
print(ret5)
item=[1,2,3,4,5,6]
random.shuffle(item)
print(item)
#结果:0.3145521479730945
#
#
#
# [11, 22]
# 1.063056970721215
# [5, 2, 3, 6, 1, 4] 随机验证码:
import random
def v_code():
ret=''
for i in range(4):
num=random.randint(0,9)
alf=chr(random.randint(65,122))
s=str(random.choice([num,alf]))
ret+=s
return ret
print(v_code())
#结果:eP2R

【3】os模块:

 import os
print(os.getcwd()) #获取当前目录
print(os.stat('修饰器.py')) #与文件相关的信息
print(os.system('dir')) #显示文件所有信息
a='C:Users\zy\PycharmProjects'
b='python全站-s3'
print(os.path.join(a,b)) #路径拼接

【4】sys模块:

 #sys.argv  命令行参数list,第一个元素是元素本身路径
#sys.exit(n) 退出程序,正常退出时exit(0)
#sys.version 获取python解释程序的版本信息
#sys.maxint 最大的int值
#sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
#sys.platform 返回操作系统平台名称

【5】json模块:(任何语言都可以)

 import json
dic={'name':'alex'} #json会将所有的单引号变成双引号,json只认识双引号
i=8
data=json.dumps(dic)
data1=json.dumps(i)
print(data)
print(data1)
print(type(data))
print(type(data1))
#结果:{"name": "alex"} #变成json字符串
#
# <class 'str'>
# <class 'str'> 在没有json之前,将一个字典存入一个文本,并且通过字典的键取值:
dic='{"name":"alex"}'
f=open('hello','w')
f.write(dic)
#将字典dic='{"name":"alex"}'已经以字符串的形式写入文本hello
f_read=open("hello","r")
data=f_read.read()
print(type(data))
data=eval(data)
print(data["name"])
#结果:<class 'str'>
# alex 使用json:
import json
dic={'name':'alex'}
dic_str=json.dumps(dic)
f=open("new_hello","w")
f.write(dic_str)
已经在new_hello这个文件里面将字典写入;
f_read=open("new_hello","r")
data=json.loads(f_read.read())
print(data["name"])
print(data)
print(type(data))
#结果:alex
# {'name': 'alex'}
# <class 'dict'>

【6】pickle模块:(与json一样,只不过json是字符串,而pickle是字节)

【7】shelve模块:(与json,pickle一样,也是进行数据传送的)

【8】XML模块:(XML是实现不同语言或者程序之间进行数据交换的协议,与json差不多)

 xml的格式如下,就是通过<>节点来区别数据结构的:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>

xml格式

 利用xml格式里面的标签内容,取标签属性,内容等.....
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson") #parse解析
root = tree.getroot()
print(root.tag) #打印root根结点的tag标签名data for i in root:
print(i.tag) #打印root后面标签的标签名country
print(i.attrib) #打印属性,打印country的属性
for j in i:
print(j.tag) #打印country后面标签的标签名...
print(j.attrib) #打印属性
print(j.text) #打印country里面标签的内容 #结果:data
#country
#{'name': 'Liechtenstein'}
#rank
#{'updated': 'yes'}
#
#year
#{}
#
#gdppc
#{}
#
#neighbor
#{'name': 'Austria', 'direction': 'E'}
#None
#neighbor
#{'name': 'Switzerland', 'direction': 'W'}
#None
#country
#{'name': 'Singapore'}
#rank
#{'updated': 'yes'}
#
#year
#{}
#
#gdppc
#{}
#
#neighbor
#{'name': 'Malaysia', 'direction': 'N'}
#None
#country
#{'name': 'Panama'}
#rank
#{'updated': 'yes'}
#
#year
#{}
#
#gdppc
#{}
#
#neighbor
#{'name': 'Costa Rica', 'direction': 'W'}
#None
#neighbor
#{'name': 'Colombia', 'direction': 'E'}
#None
 # 遍历xml文档
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson") #parse解析
root = tree.getroot()
for child in root:
print('========>', child.tag, child.attrib, child.attrib['name'])
for i in child:
print(i.tag, i.attrib, i.text)
#结果:# ========> country {'name': 'Liechtenstein'} Liechtenstein
# rank {'updated': 'yes'} 2
# year {} 2008
# gdppc {} 141100
# neighbor {'name': 'Austria', 'direction': 'E'} None
# neighbor {'name': 'Switzerland', 'direction': 'W'} None
# ========> country {'name': 'Singapore'} Singapore
# rank {'updated': 'yes'} 5
# year {} 2011
# gdppc {} 59900
# neighbor {'name': 'Malaysia', 'direction': 'N'} None
# ========> country {'name': 'Panama'} Panama
# rank {'updated': 'yes'} 69
# year {} 2011
# gdppc {} 13600
# neighbor {'name': 'Costa Rica', 'direction': 'W'} None
# neighbor {'name': 'Colombia', 'direction': 'E'} None
 # 只遍历year 节点
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson") #parse解析
root = tree.getroot()
for node in root.iter('year'):
print(node.tag, node.text) #结果:year 2008
# year 2011
# year 2011
 1#修改 import xml.etree.ElementTree as ET
tree = ET.parse("xml_lesson")
root = tree.getroot() for node in root.iter('year'):
new_year = int(node.text) + 1 #年份增加1
node.text = str(new_year)
node.set('updated', 'yes') #新增加一个属性,updated=yes
tree.write('xml_lesson')
 # 删除node
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson")
root = tree.getroot() for country in root.findall('country'):
rank = int(country.find('rank').text) #在root的子节点找,只找一个
if rank > 50:
root.remove(country) tree.write('output.xml')
 import xml.etree.ElementTree as ET

 new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = ''
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '' et = ET.ElementTree(new_xml) #生成文档对象
et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式

自己创建xml文档

【9】re模块:

正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。就其本质而言,正则表达式是一种小型的,高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

元字符:(模糊匹配)

 元字符:
转义字符\
>>> import re
>>> re.findall("I","I am LIST")
['I', 'I']
>>> re.findall("^I","I am LIST")
['I']
>>> re.findall("^I","hello I am LIST")
[]
>>> re.findall("I\b","hello I am LIST")
[]
>>> re.findall(r"I\b","hello I am LIST")
['I']
#r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义,传到re模块中。
>>> re.findall("I\\b","hello I am LIST")
['I']
>>>
>>> re.findall("c\\f","abc\ferdv")
['c\x0c']
#对于正则来说c\\f确实可以匹配到c\f,但是在python解释器读取c\\f时,会发生转义,然后交给re去执行,所以抛出异常.
>>> re.findall("c\\\\f","abc\ferdv")
#四个\\\\先经过python解释器转义成两个\\f传入re模块,转义成\f匹配!!!
 元字符:
或 a|b (匹配两个中的一个或者两个)
>>>import re
>>> re.findall(r"ka|b","sdkskaf")
['ka']
>>> re.findall(r"ka|b","sdfkbx")
['b']
>>> re.findall(r"ka|b","sdjka|bd")
['ka', 'b']
>>> re.findall(r"ka|am","sdka|amd")
['ka', 'am']
>>> re.findall(r"ka|am","dfkaoamk")
['ka', 'am']
 元字符:
()分组
import re
>>> re.findall(r"(abc)+","abcabcabc")
['abc']
>>> re.search("(?P<name>\w+)","abcccc")
<_sre.SRE_Match object; span=(0, 6), match='abcccc'>
#固定分组,其实只有\w+才有意义
>>> re.search("\d+","dsfgd23fv50").group() #整数
''
#findall表示找所有,search表示找到一个就不会往下找了
>>> re.search("(?P<name>[a-z]+)","alex15dc2").group() #找a到z的字符串
'alex'
#.group()表示将结果显示出来 >>> re.search("(?P<name>[a-z]+)","alex15dc2").group()
'alex'
>>>
>>> re.search("(?P<name>[a-z]+)\d+","alex23zy18").group()
'alex23'
>>> re.search("(?P<name>[a-z]+)\d+","alex23zy18").group("name")
'alex'
>>> re.search("(?P<name>[a-z]+)(?P<age>\d+)","alex23zy18").group("age")
''
 元字符:
一对一的匹配
'hello'.replace(old,new)
'hello'.find('pattern') 正则匹配
import re
\w与\W
print(re.findall('\w','hello egon 123'))
#['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
print(re.findall('\W','hello egon 123'))
#[' ', ' '] \s与\S
print(re.findall('\s','hello egon 123'))
#[' ', ' ', ' ', ' ']
print(re.findall('\S','hello egon 123'))
#['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3'] \n \t都是空,都可以被\s匹配
print(re.findall('\s','hello \n egon \t 123'))
#[' ', '\n', ' ', ' ', '\t', ' '] \n与\t
print(re.findall(r'\n','hello egon \n123')) #['\n']
print(re.findall(r'\t','hello egon\t123')) #['\n'] \d与\D
print(re.findall('\d','hello egon 123'))
#['1', '2', '3']
print(re.findall('\D','hello egon 123'))
#['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' '] \A与\Z
print(re.findall('\Ahe','hello egon 123'))
#['he'] \A==>^
print(re.findall('123\Z','hello egon 123'))
#['he'],\Z==>$ ^与$
print(re.findall('^h','hello egon 123')) #['h']
print(re.findall('3$','hello egon 123')) #['3'] 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
#.
print(re.findall('a.b','a1b'))
#['a1b']
print(re.findall('a.b','a1b a*b a b aaab'))
#['a1b', 'a*b', 'a b', 'aab']
print(re.findall('a.b','a\nb'))
#[]
print(re.findall('a.b','a\nb',re.S))
#['a\nb']
print(re.findall('a.b','a\nb',re.DOTALL))
#['a\nb']同上一条意思一样 #*
print(re.findall('ab*','bbbbbbb'))
#[]
print(re.findall('ab*','a'))
#['a']
print(re.findall('ab*','abbbb'))
#['abbbb'] #?
print(re.findall('ab?','a'))
#['a']
print(re.findall('ab?','abbb'))
#['ab']
#匹配所有包含小数在内的数字 #.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b'))
#['a1b22222222b'] #.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b'))
#['a1b'] #+
print(re.findall('ab+','a'))
#[]
print(re.findall('ab+','abbb'))
#['abbb'] #{n,m}
print(re.findall('ab{2}','abbb')) #['abb']
print(re.findall('ab{2,4}','abbb')) #['abb']
print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*' #[]
print(re.findall('a[1*-]b','a1b a*b a-b'))
#['a1b', 'a*b', 'a-b']
#[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
print(re.findall('a[^1*-]b','a1b a*b a-b a=b'))
#['a=b']
#[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[0-9]b','a1b a*b a-b a=b'))
#['a1b']
print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb'))
#['aeb']
print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb'))
#['aeb', 'aEb']

re模块之方法:

 re模块的方法:
import re
print(re.findall('e','alex make love') )
#['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里 print(re.search('e','alex make love').group())
#e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 print(re.match('e','alex make love'))
#None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
>>>re.match("\d+","15sfsdv").group()
'' print(re.split('[ab]','abcd'))
#['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割 print('===>',re.sub('a','A','alex make love'))
#===> Alex mAke love,不指定n,默认替换所有
print('===>',re.sub('a','A','alex make love',1))
#===> Alex make love
print('===>',re.sub('a','A','alex make love',2))
#===> Alex mAke love >>>com=re.compile("\d+")
>>>com.findall("dsgd12sfds32")
['','']

【10】logging模块:

日志级别:

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical') # WARNING:root:警告warn
# ERROR:root:错误error
# CRITICAL:root:严重critical
(默认级别为warning警告级别,默认打印到终端,所以只打印出来warning及以上的级别) import logging logging.basicConfig(level=logging.DEBUG) #改变了最低级别为debug
logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

为logging模块指定全局配置:(不常使用)

 可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,
可用参数有:
filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger的日志级别。
stream:用指定的stream创建StreamHandler。可以指定输出sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 #格式
%(name)s:Logger的名字,并非用户名。
%(levelno)s:数字形式的日志级别
%(levelname)s:文本形式的日志级别
%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
%(filename)s:调用日志输出函数的模块的文件名
%(module)s:调用日志输出函数的模块名
%(funcName)s:调用日志输出函数的函数名
%(lineno)d:调用日志输出函数的语句所在的代码行
%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s:字符串形式的当前时间。默认格式是“2003-07-0816:49:45,896”。逗号后面的是毫秒
%(thread)d:线程ID。可能没有
%(threadName)s:线程名。可能没有
%(process)d:进程ID。可能没有
%(message)s:用户输出的消息

logger:

 import logging

 logger=logging.getLogger()
fh=logging.FileHandler('test_log') #可以向文件里面发送日志
ch=logging.StreamHandler() #可以向屏幕里面发送内容
fm=logging.Formatter("%(asctime)s %(message)s")#定义日志格式,时间,信息
fh.setFormatter(fm) #将格式给fh与ch
ch.setFormatter(fm)
logger.addHandler(fh) #将fh与ch给logger
logger.addHandler(ch)
logger.setLevel('DEBUG') #设置最低级别为DEBUG logger.debug('hello')
logger.info('hello')
logger.warning('hello')
logger.error('hello')
logger.critical('hello') #结果:2018-09-07 09:54:57,169 hello
# 2018-09-07 09:54:57,169 hello
# 2018-09-07 09:54:57,169 hello
# 2018-09-07 09:54:57,170 hello
# 2018-09-07 09:54:57,170 hello

【11】configparser模块:(配置文件)

首先,创建一个文档,text
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31 [section2]
k1 = v1

创建的text文档

 import configparser

 config=configparser.ConfigParser()
config.read('a.cfg') #读取刚创建的,a.cfg文档 #查看所有的标题
res=config.sections()
print(res)
#['section1', 'section2'] #查看标题section1下所有key=value的key
options=config.options('section1')
print(options)
#['k1', 'k2', 'user', 'age', 'is_admin', 'salary'] #查看标题section1下所有key=value的(key,value)格式
item_list=config.items('section1')
print(item_list)
#[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin','true'), ('salary', '31')] #查看标题section1下user的值 字符串格式
val=config.get('section1','user')
print(val)
#egon #查看标题section1下age的值 整数格式
val1=config.getint('section1','age')
print(val1)
# #查看标题section1下is_admin的值 布尔值格式
val2=config.getboolean('section1','is_admin')
print(val2)
#True #查看标题section1下salary的值 浮点型格式
val3=config.getfloat('section1','salary')
print(val3)
#31.0
 增删改查:
import configparser config=configparser.ConfigParser()
config.read('a.cfg',encoding='utf-8') #删除整个标题section2
config.remove_section('section2') #删除标题section1下的某个k1和k2
config.remove_option('section1','k1')
config.remove_option('section1','k2') #判断是否存在某个标题
print(config.has_section('section1')) #判断标题section1下是否有user
print(config.has_option('section1','')) #添加一个标题
config.add_section('egon') #在标题egon下添加name=egon,age=18的配置
config.set('egon','name','egon')
config.set('egon','age',18) #报错,必须是字符串 #最后将修改的内容写入文件,完成最终的修改
config.write(open('a.cfg','w'))

【12】hashlib模块:

(主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法)

hash值的特点是:
1 只要传入的内容一样,得到的hash值必然一样(要用明文传输密码文件完整性校验)
2 不能由hash值返解成内容(把密码做成hash值,不应该在网络传输明文密码)
3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
 import hashlib
obj=hashlib.md5() #md5与sha256用法一样
obj.update("hello".encode("utf-8"))
print(obj.hexdigest())
#5d41402abc4b2a76b9719d911017c592 #(1)一段字符串可以转换成一段密文,且不能反解
#(2)不能反解,但可以明文转换成密文后进行比较
#(3)再加一段字符串,这种对应关系不可能被别人反解
import hashlib
obj=hashlib.md5("dsgzhbghf".encode('utf8'))
obj.update("hello".encode("utf-8"))
print(obj.hexdigest())
#d3edeba44299777b366df4bfd06f164c import hashlib
obj=hashlib.md5()
obj.update("hello".encode("utf-8"))
print(obj.hexdigest())
obj.update("root".encode("utf-8"))
print(obj.hexdigest())
#5d41402abc4b2a76b9719d911017c592
#e206121dbbe984f3bc6c6448846ed8cd(与helloroot加密结果一样)

python—模块与包的更多相关文章

  1. Python/模块与包之模块

    Python/模块与包之模块 1.什么是模块? 模块就是py文件 2.为什么要用模块? 如果在解释器上进行编码,把解释器关闭之前写的文件就不存在了,如果使用模块的话就能永久保存在磁盘中. 3.如何使用 ...

  2. Python模块、包、异常、文件(案例)

    Python模块.包.异常.文件(案例) python.py #模块 # Python中的模块(Module),是一个Python文件,以.py文件结尾,包含了Python对象定义和Python语句, ...

  3. 【Python】解析Python模块与包

    模块 模块是非常简单的Python文件,单个Python文件就是一个模块,两个文件就是两个模块. import语句是用来导入模块或者从模块里导入特定的类或者函数.如前面我们用过的math模块,从而可以 ...

  4. python 模块和包深度学习理解

    python 模块和包 简单说相当于命名空间 1,python 模块        python模块就是一个文件,里面有函数,变量等 import 模块 模块.方法 from 模块 import fu ...

  5. (三)运用Python模块和包

    1 引言 为了能够在Python项目中高效地运用Python模块和包,我们需要进一步地来了解它们是如何在Python项目中进行定义.使用和工作的. 2 Python模块和包 Python模块和包的基本 ...

  6. Python模块04/包/logging日志

    Python模块04/包/logging日志 目录 Python模块04/包/logging日志 内容大纲 1.包 2.logging日志 3.今日总结 内容大纲 1.包 2.logging日志 1. ...

  7. Python模块和包

    模块和包是python组织代码的基本方式. 模块: python的每一个脚本文件都可称之为模块,模块的名称就是脚本的文件名.例如当我们写了一个test.py的脚本文件,则可以在同目录下的另外一个脚本m ...

  8. python模块与包的导入

    1. 模块与包的区别 模块,即module,一个包含python语句的.py文件就是一个模块!每个源代码文件都会自动成为模块!没有额外的语法用来声明模块. 包,又称模块包,即module packag ...

  9. python模块及包的导入

    一.模块 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py".".pyo".".pyc".&q ...

  10. 简述Python模块和包

    我们常常会使用别人写的包,假如我们使用的是Python3.4版本,安装在windows的C盘根目录下,那么外部的包一般放在:C:\Python34\Lib\sit-packages下,此目录下有以.p ...

随机推荐

  1. python之pytest框架实现

    一.pytest测试框架简介: pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点: 简单灵活,容易上手 支持参数化 能够支持简单的单元测试和复杂的功能测试,还可以用来做se ...

  2. 【Java】Scanner类nextInt后使用nextLine无法读取输入

    首先,我们先介绍一下,在学习Java语言,对于字符串的输入,由于Scanner.next()函数无法输入空格及回车,此时,我们就必须要用Scanner.nextLine()解决这类问题, 在使用过程中 ...

  3. 1、JavaScript中的Cookie 用于存储 web 页面的用户信息。

    总结:每个浏览器都有一定数量限制的cookie.每个浏览器中,每一个cookie都有一个path路径,指向请求访问的网页. -------------------------------------- ...

  4. 五、数据类型(1):整数&&带小数点的数

    1.整数 int printf("%d",...); scanf("%d",&...); 2.带小数点的数 double printf("%f ...

  5. Java通过循环结构和switch实现简易计算器

    Java通过循环结构和switch实现简易计算器 可以循环计算,通过调用函数本身来实现重新计算 package com.shenxiaoyu.method; import java.util.Scan ...

  6. MySQL/MariaDB随笔一

    1.yum 安装后先跑一下系统自带的安全脚本,否则数据库很不安全,任何人都可以登录 [root@xixi ~]# mysql_secure_installation NOTE: RUNNING ALL ...

  7. [COCOS2DX-LUA]0-003.根据COCOS2DX热更新

    一.最近有需求就是要基于COCOS2DX-LUA进行游戏的增量更新,找了资料,发现了COCOS2DX有自带一个热更新的类,就是AssetsManager,但是该接口对于我来说有以下的缺陷 1.版本号在 ...

  8. SD.Team字符表情集大全(持续更新中..)

    一.超级可爱的字符表情集 01. <( ̄︶ ̄)> 02. <( ̄︶ ̄)/ 03. b( ̄▽ ̄)d 04. 汗( ̄口 ̄)!! 05. ╮( ̄▽ ̄)╭ 06. ╰( ̄▽ ̄)╭ 07. ╮ ...

  9. [PHP插件教程]003.PhpRedis

    PhpRedis 介绍 Mac安装步骤 安装Redis 安装PhpRedis 示例代码 介绍 Redis是一个高性能的key-value数据库. Redis提供了Java,C/C++,C#,PHP,J ...

  10. C#线程 线程进阶

    第四部分:高级线程 非阻塞同步 前面我们说过,即使在分配或增加字段的简单情况下,也需要同步.尽管锁定始终可以满足此需求,但是竞争性锁定意味着线程必须阻塞,从而遭受上下文切换的开销和调度的延迟,这在高度 ...