python(2)--nowcoder

以下内容来自牛客网python教程,仅供个人学习参考。

python3的正则表达式

正则表达式是一个特殊的字符序列,主要功能是检查某个字符串是否与某种模式匹配。
其中,re模块可以python拥有全部的正则表达式的功能。

re.match函数

re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

re.match(pattern, string, flags=0)

pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式,如区分大小写,多行匹配等

然后我们可以使用group(num)或者groups()匹配对象函数来获取匹配表达式。

group(num): 匹配整个表达式的字符串,group()可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应的元组
groups(): 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
#!/usr/bin/python

import re
print(re.match('www', 'www.nowcoder.com').span())  # 在起始位置匹配
print(re.match('com', 'www.nowcoder.com'))         # 不在起始位置匹配

(0, 3)
None

.span()返回捕获的下标。

#!/usr/bin/python3
import re

line = "Cats are smarter than dogs"
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
else:
   print ("No match!!")
re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配。

re.search(pattern, string, flags=0)

pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式,如区分大小写,多行匹配等

匹配成功re.search方法返回一个匹配的对象,否则返回None。

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

group(num): 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups(): 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
#!/usr/bin/python3

import re

print(re.search('www', 'www.nowcoder.com').span())  # 在起始位置匹配
print(re.search('com', 'www.nowcoder.com').span())         # 不在起始位置匹配

(0, 3)
(11, 14)


#!/usr/bin/python3

import re

line = "Cats are smarter than dogs";

searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)

if searchObj:
   print ("searchObj.group() : ", searchObj.group())
   print ("searchObj.group(1) : ", searchObj.group(1))
   print ("searchObj.group(2) : ", searchObj.group(2))
else:
   print ("Nothing found!!")


searchObj.group() :  Cats are smarter than dogs
searchObj.group(1) :  Cats
searchObj.group(2) :  smarter
re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,那么匹配失败,函数返回none。
而re.search匹配整个字符串,直到找到一个匹配。

#!/usr/bin/python3

import re

line = "Cats are smarter than dogs";

matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print ("match --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")

matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print ("search --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")
检索和替换

re模块中的re.sub用于替换字符串中的匹配项。

re.sub(pattern, repl, string, count=0, flags=0)

pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags : 编译时用的匹配模式,数字形式。
前三个为必选参数,后两个为可选参数。

#!/usr/bin/python3
import re

phone = "2004-959-559 # 这是一个电话号码"

# 删除注释
num = re.sub(r'#.*$', "", phone)
print ("电话号码 : ", num)

# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print ("电话号码 : ", num)

电话号码 :  2004-959-559 
电话号码 :  2004959559

repl参数是一个函数:

#!/usr/bin/python

import re

# 将匹配的数字乘于 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)

s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

compile函数:
compile用于编译正则表达式,生成一个正则表达式对象,用于match()和search()两个函数使用。

re.compile(pattern[, flags])
pattern : 一个字符串形式的正则表达式
flags 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为' . '并且包括换行符在内的任意字符(' . '不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和' # '后面的注释

>>>import re
>>> pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字
>>> m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m                                         # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0)   # 可省略 0
'12'
>>> m.start(0)   # 可省略 0
3
>>> m.end(0)     # 可省略 0
5
>>> m.span(0)    # 可省略 0
(3, 5)

group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group]) 方法返回 (start(group), end(group))
>>>import re
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)   # re.I 表示忽略大小写
>>> m = pattern.match('Hello World Wide Web')
>>> print m                               # 匹配成功,返回一个 Match 对象
<_sre.SRE_Match object at 0x10bea83e8>
>>> m.group(0)                            # 返回匹配成功的整个子串
'Hello World'
>>> m.span(0)                             # 返回匹配成功的整个子串的索引
(0, 11)
>>> m.group(1)                            # 返回第一个分组匹配成功的子串
'Hello'
>>> m.span(1)                             # 返回第一个分组匹配成功的子串的索引
(0, 5)
>>> m.group(2)                            # 返回第二个分组匹配成功的子串
'World'
>>> m.span(2)                             # 返回第二个分组匹配成功的子串索引
(6, 11)
>>> m.groups()                            # 等价于 (m.group(1), m.group(2), ...)
('Hello', 'World')
>>> m.group(3)                            # 不存在第三个分组
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group

findall:
在字符串中找出正则表达式所匹配的所有子串,并返回一个列表,如果没有则返回一个空列表。

re.findall(string[, pos[, endpos]])
string 待匹配的字符串。
pos 可选参数,指定字符串的起始位置,默认为 0。
endpos 可选参数,指定字符串的结束位置,默认为字符串的长度。

import re

pattern = re.compile(r'\d+')   # 查找数字
result1 = pattern.findall('nowcoder 123 google 456')
result2 = pattern.findall('now88coder123google456', 0, 10)

print(result1)
print(result2)

['123', '456']
['88', '12']

re.finditer:
和findall类似,不同的是finditer返回一个迭代器

re.finditer(pattern, string, flags=0)

pattern	匹配的正则表达式
string	要匹配的字符串。
flags	标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

import re

it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )

12 
32 
43 
3

re.split():
split()将字符串分割后返回字串的列表。

re.split(pattern, string[, maxsplit=0, flags=0])

pattern	匹配的正则表达式
string	要匹配的字符串。
maxsplit	分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags	标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

>>>import re
>>> re.split('\W+', 'nowcoder, nowcoder, nowcoder.')
['nowcoder', 'nowcoder', 'nowcoder', '']
>>> re.split('(\W+)', ' nowcoder, nowcoder, nowcoder.') 
['', ' ', 'nowcoder', ', ', 'nowcoder', ', ', 'nowcoder', '.', '']
>>> re.split('\W+', ' nowcoder, nowcoder, nowcoder.', 1) 
['', 'nowcoder, nowcoder, nowcoder.']

>>> re.split('a*', 'hello world')   # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
['hello world']
正则表达式对象

re.RegexObject
re.compile() 返回 RegexObject 对象。

re.MatchObject
group() 返回被 RE 匹配的字符串。

start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

re.I	使匹配对大小写不敏感
re.L	做本地化识别(locale-aware)匹配
re.M	多行匹配,影响 ^ 和 $
re.S	使 . 匹配包括换行在内的所有字符
re.U	根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X	该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
正则表达式模式

模式字符串使用一个特殊语法来表示一个正则表达式。
这里所说的模式字符串是指一些字符表示着匹配不同字符串的含义。

^	匹配字符串的开头
$	匹配字符串的末尾。
.	匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]	用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]	不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*	匹配0个或多个的表达式。
re+	匹配1个或多个的表达式。
re?	匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}	匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
re{ n,}	精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
re{ n, m}	匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b	匹配a或b
(re)	匹配括号内的表达式,也表示一个组
(?imx)	正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)	正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)	类似 (...), 但是不表示一个组
(?imx: re)	在括号中使用i, m, 或 x 可选标志
(?-imx: re)	在括号中不使用i, m, 或 x 可选标志
(?#...)	注释.
(?= re)	前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)	前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re)	匹配的独立模式,省去回溯。
\w	匹配数字字母下划线
\W	匹配非数字字母下划线
\s	匹配任意空白字符,等价于 [\t\n\r\f]。
\S	匹配任意非空字符
\d	匹配任意数字,等价于 [0-9]。
\D	匹配任意非数字
\A	匹配字符串开始
\Z	匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z	匹配字符串结束
\G	匹配最后匹配完成的位置。
\b	匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B	匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。	匹配一个换行符。匹配一个制表符, 等
\1...\9	匹配第n个分组的内容。
\10	匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

eg:

[Pp]ython	匹配 "Python" 或 "python"
rub[ye]	匹配 "ruby" 或 "rube"
[aeiou]	匹配中括号内的任意一个字母
[0-9]	匹配任何数字。类似于 [0123456789]
[a-z]	匹配任何小写字母
[A-Z]	匹配任何大写字母
[a-zA-Z0-9]	匹配任何字母及数字
[^aeiou]	除了aeiou字母以外的所有字符
[^0-9]	匹配除了数字外的字符

.	匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d	匹配一个数字字符。等价于 [0-9]。
\D	匹配一个非数字字符。等价于 [^0-9]。
\s	匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S	匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w	匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W	匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

python CGI编程

什么是CGI

CGI(Common Gateway Interface),通用网关接口,是一段程序,运行在服务器上,提供同客户端HTML页面的接口。

网页浏览

网页上点击一个链接的流程:
1.使用浏览器访问URL并连接到HTTP web服务器。
2.web服务器收到请求信息后会解析URL,并访问文件在文件服务器上是否存在,如果存在则返回文件内容,否则返回报错信息。
3.浏览器从服务器接收信息,并显示收到的文件或者是报错信息。

CGI程序可以是python脚本,perl脚本,shell脚本,c或者c++程序等。

在这里插入图片描述

web服务器支持及配置

在进行CGI编程时,确保web服务器已经配置了CGI和CGI的处理程序。

Apache支持CGI配置:
所有的http服务器执行CGI程序都保存在一个预先设置的目录,这个目录被称为CGI目录,默认情况下,linux服务器配置运行的cgi-bin目录为/var/www,若想修改指定目录,需要修改httpd.conf的配置文件:

<Directory "/var/www/cgi-bin">
   AllowOverride None
   Options +ExecCGI
   Order allow,deny
   Allow from all
</Directory>
第一个CGI程序

创建一个hello.py,放在/var/www/cgi-bin目录下

#!/usr/bin/python3

print ("Content-type:text/html")
print ()                             # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! 我是来自牛客教程的第一CGI程序</h2>')
print ('</body>')
print ('</html>')
http头部

hell.py文件内容中的“Content-type:text/html”即http头部的一部分,他会发送给浏览器告诉浏览器文件内容类型。

例如:
Content-type: text/html
Content-type:	请求的与实体对应的MIME信息。例如: Content-type:text/html
Expires: Date	响应过期的日期和时间
Location: URL	用来重定向接收方到非请求URL的位置来完成请求或标识新的资源
Last-modified: Date	请求资源的最后修改时间
Content-length: N	请求的内容长度
Set-Cookie: String	设置Http Cookie
CGI环境变量
CONTENT_TYPE	这个环境变量的值指示所传递来的信息的MIME类型。目前,环境变量CONTENT_TYPE一般都是:application/x-www-form-urlencoded,他表示数据来自于HTML表单。
CONTENT_LENGTH	如果服务器与CGI程序信息的传递方式是POST,这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。
HTTP_COOKIE	客户机内的 COOKIE 内容。
HTTP_USER_AGENT	提供包含了版本数或其他专有数据的客户浏览器信息。
PATH_INFO	这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。
QUERY_STRING	如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号'?'分隔。
REMOTE_ADDR	这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。
REMOTE_HOST	这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。
REQUEST_METHOD	提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。
SCRIPT_FILENAME	CGI脚本的完整路径
SCRIPT_NAME	CGI脚本的的名称
SERVER_NAME	这是你的 WEB 服务器的主机名、别名或IP地址。
SERVER_SOFTWARE	这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix)
get和post方法

浏览器客户端通过两种方式向服务器传递信息,这两种方法就是get和post方法

get

get方法发送编码后的用户信息到服务端,数据信息包含在请求页面的URL上,以“?”分割:

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2

comments:
get请求可以被缓存
get请求保留在浏览器的历史记录中
get请求可被收藏为书签
get请求不应该处理敏感数据
get请求有长度限制
get请求只应当用于取回数据

eg:
使用get方法向hello_get.py程序发送两个参数:

/cgi-bin/test.py?name=牛客教程&url=http://www.nowcoder.com

hello_get,py:

#!/usr/bin/python3

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

# 获取数据
site_name = form.getvalue('name')
site_url  = form.getvalue('url')

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")
表单实例:get方法

通过html表单使用get方法向服务器发送两个数据,提交的服务器脚本同样是hello_get.py文件,hello_get.html代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/hello_get.py" method="get">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
使用post方法传递数据:

使用post方法向服务器传递数据是安全可靠的,像一些敏感信息如用户密码等需要用post传递数据。

通过post处理浏览器提交的post表单数据:

#!/usr/bin/python3

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

# 获取数据
site_name = form.getvalue('name')
site_url  = form.getvalue('url')

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")
通过post处理表单向服务器脚本hello_get.py提交数据:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/hello_get.py" method="post">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
</form>
使用CGI传递checkbox:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/checkbox.py" method="POST" target="_blank">
<input type="checkbox" name="nowcoder" value="on" /> 牛客教程
<input type="checkbox" name="google" value="on" /> Google
<input type="submit" value="选择站点" />
</form>
</body>
</html>
#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('google'):
   google_flag = "是"
else:
   google_flag = "否"

if form.getvalue('nowcoder'):
   nowcoder_flag = "是"
else:
   nowcoder_flag = "否"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 牛客教程是否选择了 : %s</h2>" % nowcoder_flag)
print ("<h2> Google 是否选择了 : %s</h2>" % google_flag)
print ("</body>")
print ("</html>")
使用CGI程序传递radio数据:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/radiobutton.py" method="post" target="_blank">
<input type="radio" name="site" value="nowcoder" /> 牛客教程
<input type="radio" name="site" value="google" /> Google
<input type="submit" value="提交" />
</form>
</body>
</html>
#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('site'):
   site = form.getvalue('site')
else:
   site = "提交数据为空"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的网站是 %s</h2>" % site)
print ("</body>")
print ("</html>")
通过CGI程序传递textarea数据:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/textarea.py" method="post" target="_blank">
<textarea name="textcontent" cols="40" rows="4">
在这里输入内容...
</textarea>
<input type="submit" value="提交" />
</form>
</body>
</html>
#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('textcontent'):
   text_content = form.getvalue('textcontent')
else:
   text_content = "没有内容"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 输入的内容是:%s</h2>" % text_content)
print ("</body>")
print ("</html>")
使用CGI程序传递下拉数据:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<form action="/cgi-bin/dropdown.py" method="post" target="_blank">
<select name="dropdown">
<option value="nowcoder" selected>牛客教程</option>
<option value="google">Google</option>
</select>
<input type="submit" value="提交"/>
</form>
</body>
</html>
#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('dropdown'):
   dropdown_value = form.getvalue('dropdown')
else:
   dropdown_value = "没有内容"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>牛客教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的选项是:%s</h2>" % dropdown_value)
print ("</body>")
print ("</html>")
CGI中使用cookie语法:

在http协议中有一个很大的缺点就是不能对用户的身份进行判断,cookie的功能从而弥补了这个不足。
cookie的作用就是在客户访问脚本的时候,通过客户的浏览器,在客户的硬盘上写入记录,当下次客户访问取回数据信息,从而达到身份判别的功能。

cookie的语法:
http cookie的发送是通过http头部来实现的,早于文件传递,头部set-cookie的语法如下:

Set-cookie:name=name;expires=date;path=path;domain=domain;secure 

name=name,设置cookie值,多个用分号分割。
expires=date,cookie的有效期限
path=path,设置cookie支持的路径
domain=domain,对cookie生效的域名
secure:如果给出此标志,表示cookie只能通过ssl协议的https的服务器进行传递
cookie的接收是通过设置环境变量HTTP_COOKIE来实现,CGI程序可以通过检索该变量来获取cookie信息

cookie设置:
#!/usr/bin/python3
# 
print ('Content-Type: text/html')
print ('Set-Cookie: name="牛客教程";expires=Wed, 28 Aug 2016 18:30:00 GMT')
print ()
print ("""
<html>
  <head>
    <meta charset="utf-8">
    <title>牛客教程(nowcoder.com)</title>
  </head>
    <body>
        <h1>Cookie set OK!</h1>
    </body>
</html>
""")
检索cookie信息:

cookie信息存储在环境变量中HTTP_COOKIE中,格式为:

key1=value1;key2=value2;key3=value3....

eg:

#!/usr/bin/python3

# 导入模块
import os
import http.cookies

print ("Content-type: text/html")
print ()

print ("""
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
<h1>读取cookie信息</h1>
""")

if 'HTTP_COOKIE' in os.environ:
    cookie_string=os.environ.get('HTTP_COOKIE')
    c= http.cookies.SimpleCookie()
   # c=Cookie.SimpleCookie()
    c.load(cookie_string)

    try:
        data=c['name'].value
        print ("cookie data: "+data+"<br>")
    except KeyError:
        print ("cookie 没有设置或者已过去<br>")
print ("""
</body>
</html>
""")

文件上传实例:

HTML上传文件的表单需要设置enctype属性为multipart/form-data:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
 <form enctype="multipart/form-data" 
                     action="/cgi-bin/save_file.py" method="post">
   <p>选中文件: <input type="file" name="filename" /></p>
   <p><input type="submit" value="上传" /></p>
   </form>
</body>
</html>
#!/usr/bin/python3

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# 获取文件名
fileitem = form['filename']

# 检测文件是否上传
if fileitem.filename:
   # 设置文件路径 
   fn = os.path.basename(fileitem.filename)
   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = '文件 "' + fn + '" 上传成功'

else:
   message = '文件没有上传'

print ("""\
Content-Type: text/html\n
<html>
<head>
<meta charset="utf-8">
<title>牛客教程(nowcoder.com)</title>
</head>
<body>
   <p>%s</p>
</body>
</html>
""" % (message,))
文件下载对话框:
#!/usr/bin/python3

# HTTP 头部
print ("Content-Disposition: attachment; filename=\"foo.txt\"")
print ()
# 打开文件
fo = open("foo.txt", "rb")

str = fo.read();
print (str)

# 关闭文件
fo.close()
python mysql - mysql-connector驱动

安装:
pip install mysql-connector
测试是否安装成功:
import mysql.connector

创建数据库连接
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",       # 数据库主机地址
  user="yourusername",    # 数据库用户名
  passwd="yourpassword"   # 数据库密码
)

print(mydb)
创建数据库
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456"
)

mycursor = mydb.cursor()

mycursor.execute("CREATE DATABASE nowcoder_db")

创建之前可以先进行show进行查看是否存在:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456"
)

mycursor = mydb.cursor()

mycursor.execute("SHOW DATABASES")

for x in mycursor:
  print(x)

或者直接连接数据库,如果没有就会报错:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
创建数据表
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("CREATE TABLE sites (name VARCHAR(255), url VARCHAR(255))")
逐渐设置

创建表一般会设置一个主键(PRIMARY KEY):

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("ALTER TABLE sites ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY")

整体操作:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("CREATE TABLE sites (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), url VARCHAR(255))")
插入数据
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "INSERT INTO sites (name, url) VALUES (%s, %s)"
val = ("NOWCODER", "https://www.nowcoder.com")
mycursor.execute(sql, val)

mydb.commit()    # 数据表内容有更新,必须使用到该语句

print(mycursor.rowcount, "记录插入成功。")
批量插入

批量插入使用executemany()方法,该方法的第二个参数就是一个元组列表,包含我们要插入的数据:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "INSERT INTO sites (name, url) VALUES (%s, %s)"
val = [
  ('Google', 'https://www.google.com'),
  ('Github', 'https://www.github.com'),
  ('Taobao', 'https://www.taobao.com'),
  ('stackoverflow', 'https://www.stackoverflow.com/')
]

mycursor.executemany(sql, val)

mydb.commit()    # 数据表内容有更新,必须使用到该语句

print(mycursor.rowcount, "记录插入成功。")

# 获取该记录的id
print("1 条记录已插入, ID:", mycursor.lastrowid)
查询数据

select语句

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM sites")

myresult = mycursor.fetchall()     # fetchall() 获取所有记录

for x in myresult:
  print(x)


(1, 'NOWCODER', 'https://www.nowcoder.com')
(2, 'Google', 'https://www.google.com')
(3, 'Github', 'https://www.github.com')
(4, 'Taobao', 'https://www.taobao.com')
(5, 'stackoverflow', 'https://www.stackoverflow.com/')
(6, 'Zhihu', 'https://www.zhihu.com')

也可以获取指定的字段数据:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("SELECT name, url FROM sites")

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

('NOWCODER', 'https://www.nowcoder.com')
('Google', 'https://www.google.com')
('Github', 'https://www.github.com')
('Taobao', 'https://www.taobao.com')
('stackoverflow', 'https://www.stackoverflow.com/')
('Zhihu', 'https://www.zhihu.com')

只读取一条数据,可以使用fetchone()方法:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM sites")

myresult = mycursor.fetchone()

print(myresult)


(1, 'NOWCODER', 'https://www.nowcoder.com')
where条件语句
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "SELECT * FROM sites WHERE name ='NOWCODER'"

mycursor.execute(sql)

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

(1, 'NOWCODER', 'https://www.nowcoder.com')

也可以使用通配符:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "SELECT * FROM sites WHERE url LIKE '%code%'"

mycursor.execute(sql)

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

(1, 'NOWCODER', 'https://www.nowcoder.com')

为了防止sql注入攻击,可以使用%s占位符来转义查询的条件

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "SELECT * FROM sites WHERE name = %s"
na = ("NOWCODER", )

mycursor.execute(sql, na)

myresult = mycursor.fetchall()

for x in myresult:
  print(x)
排序

order by语句默认升序,关键字ASC,降序的关键字为DESC

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "SELECT * FROM sites ORDER BY name"

mycursor.execute(sql)

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

(3, 'Github', 'https://www.github.com')
(2, 'Google', 'https://www.google.com')
(1, 'NOWCODER', 'https://www.nowcoder.com')
(5, 'stackoverflow', 'https://www.stackoverflow.com/')
(4, 'Taobao', 'https://www.taobao.com')
(6, 'Zhihu', 'https://www.zhihu.com')
limit

需要设置查询的数据量,可以通过limit语句指定

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM sites LIMIT 3")

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

(1, 'NOWCODER', 'https://www.nowcoder.com')
(2, 'Google', 'https://www.google.com')
(3, 'Github', 'https://www.github.com')

也可以指定起始位置:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM sites LIMIT 3 OFFSET 1")  # 0 为 第一条,1 为第二条,以此类推

myresult = mycursor.fetchall()

for x in myresult:
  print(x)


(2, 'Google', 'https://www.google.com')
(3, 'Github', 'https://www.github.com')
(4, 'Taobao', 'https://www.taobao.com')
删除记录
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "DELETE FROM sites WHERE name = 'stackoverflow'"

mycursor.execute(sql)

mydb.commit()

print(mycursor.rowcount, " 条记录删除")
更新表数据

update

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "UPDATE sites SET name = 'ZH' WHERE name = 'Zhihu'"

mycursor.execute(sql)

mydb.commit()

print(mycursor.rowcount, " 条记录被修改")
删除表
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd="123456",
  database="nowcoder_db"
)
mycursor = mydb.cursor()

sql = "DROP TABLE IF EXISTS sites"  # 删除数据表 sites

mycursor.execute(sql)

py3的mysql连接-pymsql驱动

pymql是py3中使用的一个库,在py2中则使用的是mysqldb。

pymsql的安装
$ pip3 install PyMySQL
数据库连接
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute()  方法执行 SQL 查询 
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()

print ("Database version : %s " % data)

# 关闭数据库连接
db.close()


Database version : 5.5.20-log
创建表
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute() 方法执行 SQL,如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")

# 使用预处理语句创建表
sql = """CREATE TABLE EMPLOYEE (
         FIRST_NAME  CHAR(20) NOT NULL,
         LAST_NAME  CHAR(20),
         AGE INT,  
         SEX CHAR(1),
         INCOME FLOAT )"""

cursor.execute(sql)

# 关闭数据库连接
db.close()
数据库插入操作
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
         LAST_NAME, AGE, SEX, INCOME)
         VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
   # 执行sql语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 如果发生错误则回滚
   db.rollback()

# 关闭数据库连接
db.close()
数据库查询操作
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
       WHERE INCOME > %s" % (1000)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 获取所有记录列表
   results = cursor.fetchall()
   for row in results:
      fname = row[0]
      lname = row[1]
      age = row[2]
      sex = row[3]
      income = row[4]
       # 打印结果
      print ("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \
             (fname, lname, age, sex, income ))
except:
   print ("Error: unable to fetch data")

# 关闭数据库连接
db.close()


fname=Mac, lname=Mohan, age=20, sex=M, income=2000
数据库更新操作
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()
删除操作
#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交修改
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭连接
db.close()
执行事务

事务机制可以确保数据的一直性。(事务的四个属性:原子性,一致性,隔离性,持久性)
原子性:一个事务是一个不可分割的原子单位,事务中包括的操作要么都做,要么都不做。
一致性:事务必须是使数据库从一个一致性状态变成另外一个一致性状态,一致性和原子性是密切相关的。
隔离性:一个事务的执行不能不能被其他事务所干扰,各个事务之间不能相互影响

python中的事务两种方法commit和rollback

# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()
错误处理
Warning	当有严重警告时触发,例如插入数据是被截断等等。必须是 StandardError 的子类。
Error	警告以外所有其他错误类。必须是 StandardError 的子类。
InterfaceError	当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是Error的子类。
DatabaseError	和数据库有关的错误发生时触发。 必须是Error的子类。
DataError	当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是DatabaseError的子类。
OperationalError	指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是DatabaseError的子类。
IntegrityError	完整性相关的错误,例如外键检查失败等。必须是DatabaseError子类。
InternalError	数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是DatabaseError子类。
ProgrammingError	程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、 参数数量错误等等。必须是DatabaseError的子类。
NotSupportedError	不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用.rollback()函数,然而数据库并不支持事务或者事务已关闭。 必须是DatabaseError的子类。

python3网络编程

python提供两种级别的网络服务:
低级别网络服务支持基本socket,提供一些标准的sockets api,可以访问底层sockets接口的全部方法。
高级别的网络服务模块SocketServer,提供服务器中心类,简化网络服务器的开发。

什么是socket

套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求,使主机间或者进程间完成通信。

socket()函数

在python中,我们使用socket()函数来创建套接字

socket.socket([family[, type[, proto]]])
family: 套接字家族可以使AF_UNIX或者AF_INET
type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
protocol: 一般不填默认为0.
服务器端套接字
s.bind()	绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen()	开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept()	被动接受TCP客户端连接,(阻塞式)等待连接的到来
客户端套接字
s.connect()	主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex()	connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv()	接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send()	发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall()	完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
s.recvfrom()	接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto()	发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
s.close()	关闭套接字
s.getpeername()	返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname()	返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value)	设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen])	返回套接字选项的值。
s.settimeout(timeout)	设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
s.gettimeout()	返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno()	返回套接字的文件描述符。
s.setblocking(flag)	如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile()	创建一个与该套接字相关连的文件

EG:
服务端:
调用socket模块创建一个socket对象,socket对象通过调用其他函数来设置一个socket服务,通过bind函数来指定服务的port,接着使用accept方法,等待客户端连接,并返回connection对象,表示已经连到了客户端。

#!/usr/bin/python3
# 文件名:server.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
serversocket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname()

port = 9999

# 绑定端口号
serversocket.bind((host, port))

# 设置最大连接数,超过后排队
serversocket.listen(5)

while True:
    # 建立客户端连接
    clientsocket,addr = serversocket.accept()      

    print("连接地址: %s" % str(addr))

    msg='欢迎访问牛客教程!'+ "\r\n"
    clientsocket.send(msg.encode('utf-8'))
    clientsocket.close()

客户端:
客户端通过实例连接上面的服务,端口号为9999

#!/usr/bin/python3
# 文件名:client.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname() 

# 设置端口号
port = 9999

# 连接服务,指定主机和端口
s.connect((host, port))

# 接收小于 1024 字节的数据
msg = s.recv(1024)

s.close()

print (msg.decode('utf-8'))

python中其他的一些网络模块:

HTTP	网页访问	80	httplib, urllib, xmlrpclib
NNTP	阅读和张贴新闻文章,俗称为"帖子"	119	nntplib
FTP	文件传输	20	ftplib, urllib
SMTP	发送邮件	25	smtplib
POP3	接收邮件	110	poplib
IMAP4	获取邮件	143	imaplib
Telnet	命令行	23	telnetlib
Gopher	信息查找	70	gopherlib, urllib

python3 SMTP发送邮件

SMTP是简单的邮件传输协议,是一组源地址到目的地址传送邮件的规则,用于控制信件的中转方式,python中smtplib提供了这个库。

import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:nowcoder.com,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下SMTP端口号为25。
local_hostname: 如果SMTP在你的本机上,你只需要指定服务器地址为 localhost 即可。

EG:

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'lihonghe@nowcoder.com'
receivers = ['1021143684@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("牛客教程", 'utf-8')  # 发送者
message['To'] = Header("测试", 'utf-8')  # 接收者

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')

try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print("邮件发送成功")
except smtplib.SMTPException:
    print("Error: 无法发送邮件")
用python发送html格式的邮件:
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'lihonghe@nowcoder.com'
receivers = ['1021143684@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.nowcoder.com">这是一个链接</a></p>
"""
message = MIMEText(mail_msg, 'html', 'utf-8')
message['From'] = Header("牛客教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
python发送带附件的邮件:
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

sender = 'lihonghe@nowcoder.com'
receivers = ['1021143684@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

#创建一个带附件的实例
message = MIMEMultipart()
message['From'] = Header("牛客教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')

#邮件正文内容
message.attach(MIMEText('这是牛客教程Python 邮件发送测试...', 'plain', 'utf-8'))

# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
message.attach(att1)

# 构造附件2,传送当前目录下的 nowcoder.txt 文件
att2 = MIMEText(open('nowcoder.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="nowcoder.txt"'
message.attach(att2)

try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
在html文本中添加图片:
#!/usr/bin/python3

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header

sender = 'lihonghe@nowcoder.com'
receivers = ['1021143684@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header("牛客教程", 'utf-8')
msgRoot['To'] =  Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
msgRoot['Subject'] = Header(subject, 'utf-8')

msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)


mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.nowcoder.com">牛客教程链接</a></p>
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

# 指定图片为当前目录
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)

try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, msgRoot.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
通过第三方SMTP发送:

这里举例qq邮箱,需要通过获取授权码来执行

#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

my_sender='xxxxxxxxxx@qq.com'    # 发件人邮箱账号
my_pass = 'xxxxxxxxxx'           # 发件人邮箱密码
my_user='xxxxxxxxxx@qq.com'      # 收件人邮箱账号
def mail():
    ret=True
    try:
        msg=MIMEText('填写邮件内容','plain','utf-8')
        # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['From']=formataddr(["FromNowcoder",my_sender])
        # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['To']=formataddr(["FK",my_user])
        # 邮件的主题,也可以说是标题
        msg['Subject']="牛客教程发送邮件测试"

        # 发件人邮箱中的SMTP服务器,端口是25
        server=smtplib.SMTP_SSL("smtp.qq.com", 465)
        # 括号中对应的是发件人邮箱账号、邮箱密码
        server.login(my_sender, my_pass)
        # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.sendmail(my_sender,[my_user,],msg.as_string())  
        # 关闭连接
        server.quit()  
    except Exception:  # 如果 try 中的语句没有执行,则会执行下面的 ret=False
        ret=False
    return ret

ret=mail()
if ret:
    print("邮件发送成功")
else:
    print("邮件发送失败")

python3多线程

独立的线成 = 程序运行的入口 + 顺序执行的序列 + 程序的出口

每个线程都有独立的cpu寄存器,称为线程的上下文,上下文反映线程上次运行该线程cpu寄存器的状态。

线程分为 内核线程(由操作系统创建和撤销)和用户线程(不需要内核支持而用户程序中实现的线程)

python3中常用的两个模块:
_thread
threading(推荐使用)

创建线程
_thread.start_new_thread ( function, args[, kwargs] )

function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple类型。
kwargs - 可选参数。
#!/usr/bin/python3

import _thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

# 创建两个线程
try:
   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print ("Error: 无法启动线程")

while 1:
   pass

output:

Thread-1: Wed Apr  6 11:36:31 2016
Thread-1: Wed Apr  6 11:36:33 2016
Thread-2: Wed Apr  6 11:36:33 2016
Thread-1: Wed Apr  6 11:36:35 2016
Thread-1: Wed Apr  6 11:36:37 2016
Thread-2: Wed Apr  6 11:36:37 2016
Thread-1: Wed Apr  6 11:36:39 2016
Thread-2: Wed Apr  6 11:36:41 2016
Thread-2: Wed Apr  6 11:36:45 2016
Thread-2: Wed Apr  6 11:36:49 2016
线程模块

_thread提供了一个低级别的,原始的线程以及一个简单的锁。
threading模块包含了_thread模块中的所有方法外,还提供了其他方法:

threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

Thread类同样提供了一下方法:

run(): 用以表示线程活动的方法。

start():

启动线程活动。

join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

isAlive(): 返回线程是否活动的。

getName(): 返回线程名。

setName(): 设置线程名。

使用Treading模块创建线程:
通过threading.Thread创建一个子类,并实例化之后调用start方法启动新线程,即它调用了线程的run()方法:

#!/usr/bin/python3

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")
开始线程:Thread-1
开始线程:Thread-2
Thread-1: Wed Apr  6 11:46:46 2016
Thread-1: Wed Apr  6 11:46:47 2016
Thread-2: Wed Apr  6 11:46:47 2016
Thread-1: Wed Apr  6 11:46:48 2016
Thread-1: Wed Apr  6 11:46:49 2016
Thread-2: Wed Apr  6 11:46:49 2016
Thread-1: Wed Apr  6 11:46:50 2016
退出线程:Thread-1
Thread-2: Wed Apr  6 11:46:51 2016
Thread-2: Wed Apr  6 11:46:53 2016
Thread-2: Wed Apr  6 11:46:55 2016
退出线程:Thread-2
退出主线程

线程同步:
如果多个线程共同对某个数据进行修改,则会出现未知的错误,为了保证数据的正确性,需要对多个线程进行同步。

使用Tread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法
假如set从前往后将将list中的0改为1,print负责从前往后读取并打印,如果数据不同步,那么就会造成打印一半0一半1的情况,为了避免这样的情况发生,加入了锁的概念。

#!/usr/bin/python3

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开启线程: " + self.name)
        # 获取锁,用于线程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁,开启下一个线程
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")
开启线程: Thread-1
开启线程: Thread-2
Thread-1: Wed Apr  6 11:52:57 2016
Thread-1: Wed Apr  6 11:52:58 2016
Thread-1: Wed Apr  6 11:52:59 2016
Thread-2: Wed Apr  6 11:53:01 2016
Thread-2: Wed Apr  6 11:53:03 2016
Thread-2: Wed Apr  6 11:53:05 2016
退出主线程

线程优先队列
python中的Queue模块中提供了同步的,线程安全的队列类:

Queue 模块中的常用方法:

Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作

#!/usr/bin/python3

import queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print ("开启线程:" + self.name)
        process_data(self.name, self.q)
        print ("退出线程:" + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")
开启线程:Thread-1
开启线程:Thread-2
开启线程:Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
退出线程:Thread-3
退出线程:Thread-2
退出线程:Thread-1
退出主线程
python3的XML解析

可扩展标记语言,用于标记文件使其具有结构性的标记性语言:
XML用于传输和存储数据,以及对文档部件进行标记。

python对xml的解析
常见的xml编程接口有dom和sax以及ElementTree,这两种接口处理的xml文件的方式不同,使用场合也不同。
1.SAX
python标准库包含SAX解析器,sax用于事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
2.DOM
将XML数据在内存中解析成一个树,通过对树的操作来操作xml。

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
   <movie title="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>

python使用sax解析xml
sax是一种基于事件的api,利用sax解析xml文档涉及到解析器和事件处理器。
解析器负责读取xml文档,并向事件发生器发送事件。
在 Python 中使用 sax 方式处理 xml 要先引入 xml.sax 中的 parse 函数,还有 xml.sax.handler 中的 ContentHandler。

ContentHandler类方法的使用

characters(content) 方法:
从行开始,遇到标签之前,存在字符,content 的值为这些字符串。

从一个标签,遇到下一个标签之前, 存在字符,content 的值为这些字符串。

从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。

标签可以是开始标签,也可以是结束标签。

startDocument() 方法

文档启动的时候调用。

endDocument() 方法

解析器到达文档结尾时调用。

startElement(name, attrs) 方法

遇到XML开始标签时调用,name 是标签的名字,attrs 是标签的属性值字典。

endElement(name) 方法

遇到XML结束标签时调用。

make_paser方法

通过如下方法创建解析器对象:
xml.sax.make_parser( [parser_list] )

parser_list - 可选参数,解析器列表

parser方法

创建一个sax解析器并解析xml文档:
xml.sax.parse( xmlfile, contenthandler[, errorhandler])

xmlfile - xml文件名
contenthandler - 必须是一个 ContentHandler 的对象
errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler 对象

parseString方法

创建一个xml解析器并解析xml字符串
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

xmlstring - xml字符串
contenthandler - 必须是一个 ContentHandler 的对象
errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler对象

python解析xml实例

#!/usr/bin/python3

import xml.sax

class MovieHandler( xml.sax.ContentHandler ):
   def __init__(self):
      self.CurrentData = ""
      self.type = ""
      self.format = ""
      self.year = ""
      self.rating = ""
      self.stars = ""
      self.description = ""

   # 元素开始调用
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag == "movie":
         print ("*****Movie*****")
         title = attributes["title"]
         print ("Title:", title)

   # 元素结束调用
   def endElement(self, tag):
      if self.CurrentData == "type":
         print ("Type:", self.type)
      elif self.CurrentData == "format":
         print ("Format:", self.format)
      elif self.CurrentData == "year":
         print ("Year:", self.year)
      elif self.CurrentData == "rating":
         print ("Rating:", self.rating)
      elif self.CurrentData == "stars":
         print ("Stars:", self.stars)
      elif self.CurrentData == "description":
         print ("Description:", self.description)
      self.CurrentData = ""

   # 读取字符时调用
   def characters(self, content):
      if self.CurrentData == "type":
         self.type = content
      elif self.CurrentData == "format":
         self.format = content
      elif self.CurrentData == "year":
         self.year = content
      elif self.CurrentData == "rating":
         self.rating = content
      elif self.CurrentData == "stars":
         self.stars = content
      elif self.CurrentData == "description":
         self.description = content

if ( __name__ == "__main__"):

   # 创建一个 XMLReader
   parser = xml.sax.make_parser()
   # 关闭命名空间
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)

   # 重写 ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )

   parser.parse("movies.xml")
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom

使用xml.dom解析xml
一个dom解析器在解析xml文档时,一次性读取整个文档,将文档中的所有元素保存在一个树结构里,之后用dom提供的不同函数读取或修改内容和结构,也可以将修改过的重新写入xml.

#!/usr/bin/python3

from xml.dom.minidom import parse
import xml.dom.minidom

# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print ("Root element : %s" % collection.getAttribute("shelf"))

# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")

# 打印每部电影的详细信息
for movie in movies:
   print ("*****Movie*****")
   if movie.hasAttribute("title"):
      print ("Title: %s" % movie.getAttribute("title"))

   type = movie.getElementsByTagName('type')[0]
   print ("Type: %s" % type.childNodes[0].data)
   format = movie.getElementsByTagName('format')[0]
   print ("Format: %s" % format.childNodes[0].data)
   rating = movie.getElementsByTagName('rating')[0]
   print ("Rating: %s" % rating.childNodes[0].data)
   description = movie.getElementsByTagName('description')[0]
   print ("Description: %s" % description.childNodes[0].data)
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
python3 json解析

json一种轻量级的数据交换格式,即有利于人阅读,也有利于机器去读取和生成。

json.dumps(): 对数据进行编码。
json.loads(): 对数据进行解码。
在这里插入图片描述

#!/usr/bin/python3

import json

# Python 字典类型转换为 JSON 对象
data = {
    'no' : 1,
    'name' : 'Nowcoder',
    'url' : 'http://www.nowcoder.com'
}

json_str = json.dumps(data)
print ("Python 原始数据:", repr(data))
print ("JSON 对象:", json_str)
Python 原始数据: {'url': 'http://www.nowcoder.com', 'no': 1, 'name': 'Nowcoder'}
JSON 对象: {"url": "http://www.nowcoder.com", "no": 1, "name": "Nowcoder"}
python的日期和时间

python中 time 和 calendar 模块可以用于格式化日期和时间

#!/usr/bin/python3

import time;  # 引入time模块

ticks = time.time()
print ("当前时间戳为:", ticks)
当前时间戳为: 1459996086.7115328

时间戳是通过计算1970年1月1日起经过多少秒来计算的
获取当前时间

#!/usr/bin/python3

import time

localtime = time.localtime(time.time())
print ("本地时间为 :", localtime)
本地时间为 : time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=28, tm_sec=49, tm_wday=3, tm_yday=98, tm_isdst=0)

获取格式化的时间

#!/usr/bin/python3

import time

localtime = time.asctime( time.localtime(time.time()) )
print ("本地时间为 :", localtime)
本地时间为 : Thu Apr  7 10:29:13 2016

格式化日期

#!/usr/bin/python3

import time

# 格式化成2016-03-20 11:45:39形式
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

# 格式化成Sat Mar 28 22:24:24 2016形式
print (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))

# 将格式字符串转换为时间戳
a = "Sat Mar 28 22:24:24 2016"
print (time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))

获取日历

#!/usr/bin/python3

import calendar

cal = calendar.month(2016, 1)
print ("以下输出2016年1月份的日历:")
print (cal)
以下输出2016年1月份的日历:
    January 2016
Mo Tu We Th Fr Sa Su
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
python MongoDB

pymongo驱动来连接

创建数据库通过MongoClient 对象

#!/usr/bin/python3

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["nowcoderdb"]

具体的增删查改自己去搜

实例
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值