python接口编程
Python语言的主要特征如下:
①Python语法优雅,程序编码简单易读。
②Python易上手,通过简单的操作就能让你写的程序运行。Python非常适合用来做原型开发或其他专门的编码任务,同时又不用为了维护而烦恼。
③Python拥有大量的标准库来支持一般的编码任务,例如连接网络服务器、用正则表达式搜索文字、读取和修改文件等。
④Python的交互模式可以很方便地检测代码片段。同时Python其实也自带了一个叫做IDLE的集成开发环境,初学者可以利用它方便地创建、运行、测试和调试Python程序。
⑤Python通过添加新的模块可以很容易进行扩展,这些模块可以是通过类似C或C++等编译型语言执行应用的。注意,Python是解释型脚本语言。
⑥Python也可以被嵌入应用中来提供一个可编程的接口。
⑦Python可以在任何环境运行,包括Mac OS X,Windows,Linux和Unix,通过非官方的构建,也可以在android和ios上运行。
⑧Python双重免费。首先下载和使用或是在你的应用中内置Python是完全免费的。其次Python可以被自由修改然后再发布,因为语言是完全开源的。
❷ 后端编程Python3-数据库编程
对大多数软件开发者而言,术语数据库通常是指RDBMS(关系数据库管理系统), 这些系统使用表格(类似于电子表格的网格),其中行表示记录,列表示记录的字段。表格及其中存放的数据是使用sql (结构化査询语言)编写的语句来创建并操纵的。Python提供了用于操纵SQL数据库的API(应用程序接口),通常与作为标准的SQLite 3数据库一起发布。
另一种数据库是DBM (数据库管理器),其中存放任意数量的键-值项。Python 的标准库提供了几种DBM的接口,包括某些特定于UNIX平台的。DBM的工作方式 与Python中的字典类似,区别在于DBM通常存放于磁盘上而不是内存中,并且其键与值总是bytes对象,并可能受到长度限制。本章第一节中讲解的shelve模块提供了方便的DBM接口,允许我们使用字符串作为键,使用任意(picklable)对象作为值。
如果可用的 DBM 与 SQLite 数据库不够充分,Python Package Index, pypi.python.org/pypi中提供了大量数据库相关的包,包括bsddb DBM ("Berkeley DB"),对象-关系映射器,比如SQLAlchemy (www.sqlalchemy.org),以及流行的客户端/服务器数据的接口,比如 DB2、Informix、Ingres、MySQL、ODBC 以及 PostgreSQL。
本章中,我们将实现某程序的两个版本,该程序用于维护一个DVD列表,并追踪每个DVD的标题、发行年份、时间长度以及发行者。该程序的第一版使用DBM (通过shelve模块)存放其数据,第二版则使用SQLite数据库。两个程序都可以加载与保存简单的XML格式,这使得从某个程序导出DVD数据并将其导入到其他程序成为可能。与DBM版相比,基于SQL的程序提供了更多一些的功能,并且其数据设计也稍干净一些。
12.1 DBM数据库
shelve模块为DBM提供了一个wrapper,借助于此,我们在与DBM交互时,可以将其看做一个字典,这里是假定我们只使用字符串键与picklable值,实际处理时, shelve模块会将键与值转换为bytes对象(或者反过来)。
由于shelve模块使用的是底层的DBM,因此,如果其他计算机上没有同样的DBM,那么在某台计算机上保存的DBM文件在其他机器上无法读取是可能的。为解决这一问题,常见的解决方案是对那些必须在机器之间可传输的文件提供XML导入与导出功能,这也是我们在本节的DVD程序dvds-dbm.py中所做的。
对键,我们使用DVD的标题;对值,则使用元组,其中存放发行者、发行年份以及时间。借助于shelve模块,我们不需要进行任何数据转换,并可以把DBM对象当做一个字典进行处理。
程序在结构上类似于我们前面看到的那种菜单驱动型的程序,因此,这里主要展示的是与DBM程序设计相关的那部分。下面给出的是程序main()函数中的一部分, 忽略了其中菜单处理的部分代码。
db = None
try:
db = shelve.open(filename, protocol=pickle.HIGHEST_PROTOCOL)
finally:
if db is not None:
db.dose()
这里我们已打开(如果不存在就创建)指定的DBM文件,以便于对其进行读写操作。每一项的值使用指定的pickle协议保存为一个pickle,现有的项可以被读取, 即便是使用更底层的协议保存的,因为Python可以计算出用于读取pickle的正确协议。最后,DBM被关闭——其作用是清除DBM的内部缓存,并确保磁盘文件可以反映出已作的任何改变,此外,文件也需要关闭。
该程序提供了用于添加、编辑、列出、移除、导入、导出DVD数据的相应选项。除添加外,我们将忽略大部分用户接口代码,同样是因为已经在其他上下文中进行了展示。
def add_dvd(db):
title = Console.get_string("Title", "title")
if not title:
return
director = Console.get_string("Director", "director")
if not director:
return
year = Console.get_integer("Year", "year",minimum=1896,
maximum=datetime,date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes“, minimum=0, maximum=60*48)
db[title] = (director, year, ration)
db.sync()
像程序菜单调用的所有函数一样,这一函数也以DBM对象(db)作为其唯一参数。该函数的大部分工作都是获取DVD的详细资料,在倒数第二行,我们将键-值项存储在DBM文件中,DVD的标题作为键,发行者、年份以及时间(由shelve模块pickled在一起)作为值。
为与Python通常的一致性同步,DBM提供了与字典一样的API,因此,除了 shelve.open() 函数(前面已展示)与shelve.Shelf.sync()方法(该方法用于清除shelve的内部缓存,并对磁盘上文件的数据与所做的改变进行同步——这里就是添加一个新项),我们不需要学习任何新语法。
def edit_dvd(db):
old_title = find_dvd(db, "edit")
if old_title is None:
return
title = Console.get.string("Title", "title", old_title)
if not title:
return
director, year, ration = db[old_title]
...
db[title]= (director, year, ration)
if title != old_title:
del db[old_title]
db.sync()
为对某个DVD进行编辑,用户必须首先选择要操作的DVD,也就是获取DVD 的标题,因为标题用作键,值则用于存放其他相关数据。由于必要的功能在其他场合 (比如移除DVD)也需要使用,因此我们将其实现在一个单独的find_dvd()函数中,稍后将査看该函数。如果找到了该DVD,我们就获取用户所做的改变,并使用现有值作为默认值,以便提高交互的速度。(对于这一函数,我们忽略了大部分用户接口代码, 因为其与添加DVD时几乎是相同的。)最后,我们保存数据,就像添加时所做的一样。如果标题未作改变,就重写相关联的值;如果标题已改变,就创建一个新的键-值对, 并且需要删除原始项。
def find_dvd(db, message):
message = "(Start of) title to " + message
while True:
matches =[]
start = Console.get_string(message, "title")
if not start:
return None
for title in db:
if title.lower().startswith(start.lower()):
matches.append(title)
if len(matches) == 0:
print("There are no dvds starting with", start)
continue
elif len(matches) == 1:
return matches[0]
elif len(matches) > DISPLAY_LIMIT:
print("Too many dvds start with {0}; try entering more of the title".format(start)
continue
else:
matches = sorted(matches, key=str.lower)
for i, match in enumerate(matches):
print("{0}: {1}".format(i+1, match))
which = Console.get_integer("Number (or 0 to cancel)",
"number", minimum=1, maximum=len(matches))
return matches[which - 1] if which != 0 else None
为尽可能快而容易地发现某个DVD,我们需要用户只输入其标题的一个或头几个字符。在具备了标题的起始字符后,我们在DBM中迭代并创建一个匹配列表。如果只有一个匹配项,就返回该项;如果有几个匹配项(但少于DISPLAY_LIMIT, 一个在程序中其他地方设置的整数),就以大小写不敏感的顺序展示所有这些匹配项,并为每一项设置一个编号,以便用户可以只输入编号就可以选择某个标题。(Console.get_integer()函数可以接受0,即便最小值大于0,以便0可以用作一个删除值。通过使用参数allow_zero=False, 可以禁止这种行为。我们不能使用Enter键,也就是说,没有什么意味着取消,因为什么也不输入意味着接受默认值。)
def list_dvds(db):
start =”"
if len(db)> DISPLAY.LIMIT:
start = Console.get_string(“List those starting with [Enter=all]”, "start”)
print()
for title in sorted(db, key=str.lower):
if not start or title.Iower().startswith(start.lower()):
director, year, ration = db[title]
print("{title} ({year}) {ration} minute{0}, by "
"{director}".format(Util.s(ration),**locals()))
列出所有DVD (或者那些标题以某个子字符串引导)就是对DBM的所有项进行迭代。
Util.s()函数就是简单的s = lambda x: "" if x == 1 else "s",因此,如果时间长度不是1分钟,就返回"s"。
def remove_dvd(db):
title = find_dvd(db, "remove")
if title is None:
return
ans = Console.get_bool("Remove {0}?".format(title), "no")
if ans:
del db[title]
db.sync()
要移除一个DVD,首先需要找到用户要移除的DVD,并请求确认,获取后从DBM中删除该项即可。
到这里,我们展示了如何使用shelve模块打开(或创建)一个DBM文件,以及如何向其中添加项、编辑项、对其项进行迭代以及移除某个项。
遗憾的是,在我们的数据设计中存在一个瑕疵。发行者名称是重复的,这很容易导致不一致性,比如,发行者Danny DeVito可能被输入为"Danny De Vito",用于 一个电影;也可以输入为“Danny deVito",用于另一个。为解决这一问题,可以使用两个DBM文件,主DVD文件使用标题键与(年份,时间长度,发行者ID)值; 发行者文件使用发行者ID (整数)键与发行者名称值。下一节展示的SQL数据库 版程序将避免这一瑕疵,这是通过使用两个表格实现的,一个用于DVD,另一个用于发行者。
12.2 SQL数据库
大多数流行的SQL数据库的接口在第三方模块中是可用的,Python带有sqlite3 模块(以及SQLite 3数据库),因此,在Python中,可以直接开始数据库程序设计。SQLite是一个轻量级的SQL数据库,缺少很多诸如PostgreSQL这种数据库的功能, 但非常便于构造原型系统,并且在很多情况下也是够用的。
为使后台数据库之间的切换尽可能容易,PEP 249 (Python Database API Specification v2.0)提供了称为DB-API 2.0的API规范。数据库接口应该遵循这一规范,比如sqlite3模块就遵循这一规范,但不是所有第三方模块都遵循。API规范中指定了两种主要的对象,即连接对象与游标对象。表12-1与表12-2中分别列出了这两种对象必须支持的API。在sqlite3模块中,除DB-API 2.0规范必需的之外,其连接对象与游标对象都提供了很多附加的属性与方法。
DVD程序的SQL版本为dvds.sql.py,该程序将发行者与DVD数据分开存储,以 避免重复,并提供一个新菜单,以供用户列出发行者。该程序使用的两个表格在图12-1
def connect(filename):
create= not os.path.exists(filename)
db = sqlite3.connect(filename)
if create:
cursor = db.cursor()
cursor.execute("CREATE TABLE directors ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"name TEXT UNIQUE NOT NULL)")
cursor.execute("CREATE TABLE dvds ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"title TEXT NOT NULL, "
"year INTEGER NOT NULL,"
"ration INTEGER NOT NULL, "
"director_id INTEGER NOT NULL, ”
"FOREIGN KEY (director_id) REFERENCES directors)")
db.commit()
return db
sqlite3.connect()函数会返回一个数据库对象,并打开其指定的数据库文件。如果该文件不存在,就创建一个空的数据库文件。鉴于此,在调用sqlite3.connect()之前,我们要注意数据库是否是准备从头开始创建,如果是,就必须创建该程序要使用的表格。所有査询都是通过一个数据库游标完成的,可以从数据库对象的cursor()方法获取。
注意,两个表格都是使用一个ID字段创建的,ID字段有一个AUTOINCREMENT 约束——这意味着SQLite会自动为ID字段赋予唯一性的数值,因此,在插入新记录时,我们可以将这些字段留给SQLite处理。
SQLite支持有限的数据类型——实际上就是布尔型、数值型与字符串——但使用数据'‘适配器”可以对其进行扩展,或者是扩展到预定义的数据类型(比如那些用于日期与datetimes的类型),或者是用于表示任意数据类型的自定义类型。DVD程序并不需要这一功能,如果需要,sqlite3模块的文档提供了很多详细解释。我们使用的外部键语法可能与用于其他数据库的语法不同,并且在任何情况下,只是记录我们的意图,因为SQLite不像很多其他数据库那样需要强制关系完整性,sqlite3另一点与众不同的地方在于其默认行为是支持隐式的事务处理,因此,没有提供显式的“开始事务” 方法。
def add_dvd(db):
title = Console.get_string("Title", "title")
if not title:
return
director = Console.get_string("Director", "director")
if not director:
return
year = Console.get_integer("Year", "year”, minimum=1896,
maximum=datetime.date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes",
minimum=0,maximum=60*48)
director_id = get_and_set_director(db, director)
cursor = db.cursor()
cursor.execute("INSERT INTO dvds ”
"(title, year, ration, director_id)"
"VALUES (?, ?, ?, ?)",
(title, year, ration, director_id))
db.commit()
这一函数的开始代码与dvds-dbm.py程序中的对应函数一样,但在完成数据的收集后,与原来的函数有很大的差别。用户输入的发行者可能在也可能不在directors表格中,因此,我们有一个get_and_set_director()函数,在数据库中尚无某个发行者时, 该函数就将其插入到其中,无论哪种情况都返回就绪的发行者ID,以便在需要的时候插入到dvds表。在所有数据都可用后,我们执行一条SQL INSERT语句。我们不需要指定记录ID,因为SQLite会自动为我们提供。
在査询中,我们使用问号(?)作为占位符,每个?都由包含SQL语句的字符串后面的序列中的值替代。命名的占位符也可以使用,后面在编辑记录时我们将看到。尽管避免使用占位符(而只是简单地使用嵌入到其中的数据来格式化SQL字符串)也是可能的,我们建议总是使用占位符,并将数据项正确编码与转义的工作留给数据库模块来完成。使用占位符的另一个好处是可以提高安全性,因为这可以防止任意的SQL 被恶意地插入到一个査询中。
def get_and_set_director(db, director):
director_id = get_director_id(db, director)
if directorjd is not None:
return director_id
cursor = db.cursor()
cursor.execute("lNSERT INTO directors (name) VALUES (?)”,(director,))
db.commit()
return get_director_id(db, director)
这一函数返回给定发行者的ID,并在必要的时候插入新的发行者记录。如果某个记录被插入,我们首先尝试使用get_director_id()函数取回其ID。
def get_director_id(db, director):
cursor = db.cursor()
cursor.execute("SELECT id FROM directors WHERE name=?",(director,))
fields = cursor.fetchone()
return fields[0] if fields is not None else None
get_director_id()函数返回给定发行者的ID,如果数据库中没有指定的发行者,就返回None。我们使用fetchone()方法,因为或者有一个匹配的记录,或者没有。(我们知道,不会有重复的发行者,因为directors表格的名称字段有一个UNIQUE约束,在任何情况下,在添加一个新的发行者之前,我们总是先检査其是否存在。)这种取回方法总是返回一个字段序列(如果没有更多的记录,就返回None)。即便如此,这里我们只是请求返回一个单独的字段。
def edit_dvd(db):
title, identity = find_dvd(db, "edit")
if title is None:
return
title = Console.get_string("Title","title", title)
if not title:
return
cursor = db.cursor()
cursor.execute("SELECT dvds.year, dvds.ration, directors.name"
“FROM dvds, directors "
"WHERE dvds.director_id = directors.id AND "
"dvds.id=:id", dict(id=identity))
year, ration, director = cursor.fetchone()
director = Console.get_string("Director", "director", director)
if not director:
return
year = Console,get_integer("Year","year", year, 1896,datetime.date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes",
ration, minimum=0, maximum=60*48)
director_id = get_and_set_director(db, director)
cursor.execute("UPDATE dvds SET title=:title, year=:year,"
"ration=:ration, director_id=:directorjd "
"WHERE id=:identity", locals())
db.commit()
要编辑DVD记录,我们必须首先找到用户需要操纵的记录。如果找到了某个记录,我们就给用户修改其标题的机会,之后取回该记录的其他字段,以便将现有值作为默认值,将用户的输入工作最小化,用户只需要按Enter键就可以接受默认值。这里,我们使用了命名的占位符(形式为:name),并且必须使用映射来提供相应的值。对SELECT语句,我们使用一个新创建的字典;对UPDATE语句,我们使用的是由 locals()返回的字典。
我们可以同时为这两个语句都使用新字典,这种情况下,对UPDATE语句,我们可以传递 dict(title=title, year=year, ration=ration, director_id=director_id, id=identity)),而非 locals()。
在具备所有字段并且用户已经输入了需要做的改变之后,我们取回相应的发行者ID (如果必要就插入新的发行者记录),之后使用新数据对数据库进行更新。我们采用了一种简化的方法,对记录的所有字段进行更新,而不仅仅是那些做了修改的字段。
在使用DBM文件时,DVD标题被用作键,因此,如果标题进行了修改,我们就需要创建一个新的键-值项,并删除原始项。不过,这里每个DVD记录都有一个唯一性的ID,该ID是记录初次插入时创建的,因此,我们只需要改变任何其他字段的值, 而不需要其他操作。
def find_dvd(db, message):
message = "(Start of) title to " + message
cursor = db.cursor()
while True: .
start = Console.get_stnng(message, "title")
if not start:
return (None, None)
cursor.execute("SELECT title, id FROM dvds "
"WHERE title LIKE ? ORDER BY title”,
(start +"%",))
records = cursor.fetchall()
if len(records) == 0:
print("There are no dvds starting with", start)
continue
elif len(records) == 1:
return records[0]
elif len(records) > DISPLAY_LIMIT:
print("Too many dvds ({0}) start with {1}; try entering "
"more of the title".format(len(records),start))
continue
else:
for i, record in enumerate(records):
print("{0}:{1}".format(i + 1, record[0]))
which = Console.get_integer("Number (or 0 to cancel)",
"number", minimum=1, maximum=len(records))
return records[which -1] if which != 0 else (None, None)
这一函数的功能与dvdsdbm.py程序中的find_dvd()函数相同,并返回一个二元组 (DVD标题,DVD ID)或(None, None),具体依赖于是否找到了某个记录。这里并不需要在所有数据上进行迭代,而是使用SQL通配符(%),因此只取回相关的记录。
由于我们希望匹配的记录数较小,因此我们一次性将其都取回到序列的序列中。如果有不止一个匹配的记录,但数量上又少到可以显示,我们就打印记录,并将每条记录附带一个数字编号,以便用户可以选择需要的记录,其方式与在dvds-dbm.py程序中所做的类似:
def list_dvds(db):
cursor = db.cursor()
sql = ("SELECT dvds.title, dvds.year, dvds.ration, "
"directors.name FROM dvds, directors "
"WHERE dvds.director_id = directors.id")
start = None
if dvd_count(db) > DISPLAY_LIMIT:
start = Console.get_string("List those starting with [Enter=all]", "start")
sql += " AND dvds.title LIKE ?"
sql += ” ORDER BY dvds.title"
print()
if start is None:
cursor.execute(sql)
else:
cursor.execute(sql, (start +"%",))
for record in cursor:
print("{0[0]} ({0[1]}) {0[2]} minutes, by {0[3]}".format(record))
要列出每个DVD的详细资料,我们执行一个SELECT査询。该査询连接两个表,如果记录(由dvd_count()函数返回)数量超过了显示限制值,就将第2个元素添加到WHERE 分支,之后执行该査询,并在结果上进行迭代。每个记录都是一个序列,其字段是与 SELECT査询相匹配的。
def dvd_count(db):
cursor = db.cursor()
cursor.execute("SELECT COUNT(*) FROM dvds")
return cursor.fetchone()[0]
我们将这几行代码放置在一个单独的函数中,因为我们在几个不同的函数中都需要使用这几行代码。
我们忽略了 list_directors()函数的代码,因为该函数在结构上与list_dvds()函数非常类似,只不过更简单一些,因为本函数只列出一个字段(name)。
def remove_dvd(db):
title, identity = find_dvd(db, "remove")
if title is None:
return
ans = Console.get_bool("Remove {0}?".format(title), "no")
if ans:
cursor = db.cursor()
cursor.execute("DELETE FROM dvds WHERE id=?", (identity,))
db.commit()
在用户需要删除一个记录时,将调用本函数,并且本函数与dvds-dbm.py程序中 相应的函数是非常类似的。
到此,我们完全查阅了 dvds-sql.py程序,并且了解了如何创建数据库表格、选取 记录、在选定的记录上进行迭代以及插入、更新与删除记录。使用execute()方法,我们可以执行底层数据库所支持的任意SQL语句。
SQLite提供了比我们这里使用的多得多的功能,包括自动提交模式(以及任意其他类型的事务控制),以及创建可以在SQL查询内执行的函数的能力。提供一个工厂函数并用于控制对每个取回的记录返回什么(比如,一个字典或自定义类型,而不是字段序列)也是可能的。此外,通过传递“:memory:”作为文件名,创建内存中的SQLite 数据库也是可能的。
以上内容部分摘自视频课程05后端编程Python22 数据库编程,更多实操示例请参照视频讲解。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领。
❸ python编写接口,请求url应该如何确定
1、是一个接口
2、程序需要运行后才能访问,可以部署到服务器上,程序一旦运行是守护进程,只要不关闭程序一直会运行
3、请求的url根据'/xxx'来确定,请求的类型 methods=['get']
❹ Python能做什么,能够开发什么项目
Python是一种计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。
Python是一种解释型脚本语言,可以应用于Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发这些领域。
Python的应用
1、系统编程
提供API(Application Programming Interface应用程序编程接口),能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具。
2、图形处理
有PIL、Tkinter等图形库支持,能方便进行图形处理。
3、数学处理
NumPy扩展提供大量与许多标准数学库的接口。
4、文本处理
python提供的re模块能支持正则表达式,还提供SGML,XML分析模块,许多程序员利用python进行XML程序的开发。
5、数据库编程
程序员可通过遵循Python DB-API(数据库应用程序编程接口)规范的模块与Microsoft SQL Server,Oracle,Sybase,DB2,MySQL、SQLite等数据库通信。python自带有一个Gadfly模块,提供了一个完整的SQL环境。
6、网络编程
提供丰富的模块支持sockets编程,能方便快速地开发分布式应用程序。很多大规模软件开发计划例如Zope,Mnet 及BitTorrent. Google都在广泛地使用它。
7、Web编程
应用的开发语言,支持最新的XML技术。
8、多媒体应用
Python的PyOpenGL模块封装了“OpenGL应用程序编程接口”,能进行二维和三维图像处理。PyGame模块可用于编写游戏软件。
9、pymo引擎
PYMO全称为python memories off,是一款运行于Symbian S60V3,Symbian3,S60V5, Symbian3, Android系统上的AVG游戏引擎。因其基于python2.0平台开发,并且适用于创建秋之回忆(memories off)风格的AVG游戏,故命名为PYMO。
10、黑客编程
python有一个hack的库,内置了你熟悉的或不熟悉的函数,但是缺少成就感。
❺ 编程语言python是用来干什么的
python的作用:
1、系统编程:提供API(ApplicationProgramming
Interface应用程序编程接口),能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具。
2、图形处理:有PIL、Tkinter等图形库支持,能方便进行图形处理。
3、数学处理:NumPy扩展提供大量与许多标准数学库的接口。
4、文本处理:python提供的re模块能支持正则表达式,还提供SGML,XML分析模块,许多程序员利用python进行XML程序的开发。
5、数据库编程:程序员可通过遵循PythonDB-API(数据库应用程序编程接口)规范的模块与MicrosoftSQL Server,Oracle,Sybase,DB2,MySQL、SQLite等数据库通信。python自带有一个Gadfly模块,提供了一个完整的SQL环境。
(5)python接口编程扩展阅读:
python中文就是蟒蛇的意思。在计算机中,它是一种编程语言。Python(英语发音:/ˈpaɪθən/),是一种面向对象、解释型计算机程序设计语言,由GuidovanRossum于1989年底发明,第一个公开发行版发行于1991年。Python语法简洁而清晰,具有丰富和强大的类库。
它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写。
比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C++重写。1发展历程编辑自从20世纪90年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程。Python已经成为最受欢迎的程序设计语言之一。
❻ Python网络编程6-使用Pysnmp实现简单网管
简单网络管理协议SNMP(Simple Network Management Protocol)用于网络设备的管理。SNMP作为广泛应用于TCP/IP网络的网络管理标准协议,提供了统一的接口,从而实现了不同种类和厂商的网络设备之间的统一管理。
SNMP协议分为三个版本:SNMPv1、SNMPv2c和SNMPv3。
SNMP系统由网络管理系统NMS(Network Management System)、SNMP Agent、被管对象Management object和管理信息库MIB(Management Information Base)四部分组成。
SNMP查询是指NMS主动向SNMP Agent发送查询请求,如图1-3所示。SNMP Agent接收到查询请求后,通过MIB表完成相应指令,并将结果反馈给NMS。SNMP查询操作有三种:Get、GetNext和GetBulk。SNMPv1版本不支持GetBulk操作。
不同版本的SNMP查询操作的工作原理基本一致,唯一的区别是SNMPv3版本增加了身份验证和加密处理。下面以SNMPv2c版本的Get操作为例介绍SNMP查询操作的工作原理。假定NMS想要获取被管理设备MIB节点sysContact的值,使用可读团体名为public,过程如下所示:
SNMP设置是指NMS主动向SNMP Agent发送对设备进行Set操作的请求,如下图示。SNMP Agent接收到Set请求后,通过MIB表完成相应指令,并将结果反馈给NMS。
不同版本的SNMP Set操作的工作原理基本一致,唯一的区别是SNMPv3版本增加了身份验证和加密处理。下面以SNMPv3版本的Set操作为例介绍SNMP Set操作的工作原理。
假定NMS想要设置被管理设备MIB节点sysName的值为HUAWEI,过程如下所示:
SNMPv1和SNMPv2c的Set操作报文格式如下图所示。一般情况下,SNMPv3的Set操作信息是经过加密封装在SNMP PDU中,其格式与SNMPv2c的Set操作报文格式一致。
SNMP Traps是指SNMP Agent主动将设备产生的告警或事件上报给NMS,以便网络管理员及时了解设备当前运行的状态。
SNMP Agent上报SNMP Traps有两种方式:Trap和Inform。SNMPv1版本不支持Inform。Trap和Inform的区别在于,SNMP Agent通过Inform向NMS发送告警或事件后,NMS需要回复InformResponse进行确认。
在Ensp中搭建网络环境,在R2上启用SNMP作为SNMP agent,Linux主机作为NMS;为方便观察SNMP报文格式,在R2使用SNMP的版本为v2c。
通过下面的Python脚本获取R2的系统信息与当前的主机名
运行结果如下
在R2接口上抓包结果如下,Linux主机向R2的161端口发送SNMP get-request报文,可以看到SNMP使用的版本为v2c,设置的团体名为public,随机生成了一个request-id,变量绑定列表(Variable bindings),即要查询的OID,但Value为空;值得注意的是这些信息都是明文传输的,为了安全在实际环境中应使用SNMPv3。
通过下面的Python脚本获取R2的接口信息。
运行结果如下:
在R2接口抓包结果如下,getBuikRequest相比get-request设置了一个max-repetitions字段,表明最多执行get操作的次数。Variable bindings中请求的OID条目只有一条。
下面Python脚本用于设置R2的主机名为SNMPv2R2。
运行结果如下
在路由器上可以看到主机名有R2变为了SNMPv2R2。
get-response数据包内容与set-request中无异。
下面Python脚本用于接收,R2发送的Trap,并做简单解析。
先运行该脚本,之后再R2上手动将一个接口shutdown,结果如下:
接口上抓包结果如下,此时团体名用的是public,data部分表明是trap。
由于Ensp中的通用路由器认证算法只支持des56,而pysnmp不支持该算法,因此使用AR路由器配置SNMPv3。
使用下面Python脚本发送snmpv3 get报文获取设备系统信息。
抓包结果如下,首先发送get-resques进行SNMPv3认证请求,随机生成一个msgID,认证模式为USM,msgflgs中Reportable置1要求对方发送report,其他为置0,表示不进行加密与鉴权;另外安全参数,认证参数、加密参数都为空,此时不携带get请求数据。
路由器给NMS回复report,msgID与resquest一致,Msgflgs中各位都置0,同时回复使用的安全引擎,认证与加密参数为空,不进行认证与加密,因此能看到data中的数据。
AR1收到请求后进行回复,数据包中msgflags标志位中除reportable外其他位都置1,表示不需要回复,同时进行加密与鉴权。同样也可以看到认证用户为testuser,认证参数与加密参数都有填充,data部分也是同样加密。
参考:
什么是SNMP - 华为 (huawei.com)
AR100-S V300R003 MIB参考 - 华为 (huawei.com)
SNMP library for Python — SNMP library for Python 4.4 documentation (pysnmp.readthedocs.io)
❼ python怎么做接口测试工具
之前使用过urllib和urllib2做接口测试,在做的途中,感觉使用urllib2直接进行的get,post 请求并没有那么好用。作为测试人员,所需要的测试工具应当以方便为第一要务,测试的耗时只要是真正的无人值守,耗时不是太久的都可以接受。所以,本人又尝试了一个新的包:requests。
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。更重要的一点是它支持 Python3 !推荐一篇文章,上面有该包的详细说明传送门,以下只会写到我用到的部分,所以更多的了解需要自己去搜资料
好了,我们开始吧!!
接口测试中重要的部分:
1.get和post方法
2.用到的参数
3.请求头
4.cookie
5.日志输出
6.如何调试你的程序--借助fiddler
按照以上的顺序,我将一一说明我的搞法,因为编码能力有限,所以可能看着很low
一、get和post
requests包很好的实现了post和get方法,示例:
1 import requests2 response_get = requests.get(url, data, headers, cookies)3 response_post = requests.post(url, data, headers, cookies)
其他的访问方式如put,head等等,用法几乎都是如此,因为没用到,所以省略
现在一般的接口返回值有页面和json俩种,按照需求,可以分别使用response.text或者response.content获取,text获取的是unicode类型的返回值,而content返回值是str类型,所以我一般使用content来获取返回值,因为这样获取的返回值可以直接使用正则或者in的方式来验证返回值结果是否正确。
我自己为了实现接口的自动访问,所以又在requests上面加了一层封装,就像下面这样:
三、cookie
一款产品的接口测试中必定会使用登录状态,需要使用cookie实现,之前写过使用cookiejar获取cookie,requests中获取cookie的方法更为简单,不过首先你得知道是哪个接口set了cookie,不过一般是登录啦。登录接口访问之后set了cookie,那好,就去调用登录接口,然后拿到搞回来的cookie:
# 只需要这样!!login = requests.post(login_url, data=login_data, headers=login_header)
cookie = login.cookies
这个cookie就是登录状态了,拿着随便用,需要登录的就直接cookies=cookies
四、日志输出
这里注意看第二步中接口数据,有接口描述,也有接口是啥,第一步中又把content做成返回值了,具体拼接方式自己想吧,东西全有了,想写啥写啥,还可以加上获取本地时间的api获取接口运行时间,log文件该长啥样是门学问,这里就不献丑了。
五、借用fiddler调试你的脚本
requests允许使用代理访问,这有啥用,真有!fiddler是一款截包改包的工具,而且通过扩展可以进行请求间的比对,这样让你的程序访问的请求和真正正确的请求作对比,为啥我的程序访问出错?是不是缺了请求头?参数是不是丢了?cookie是不是少了?很容易看出来。写法如下:
proxies = { "http": "http://127.0.0.1:8888", "https": "http://127.0.0.1:8888"}
requests.post(url, proxies=proxies)
这样就可以走代理了,除fiddler以外还有charles和burp suite可以使用,具体看个人喜好吧。
❽ 如何使用Python实现并发编程
多线程几乎是每一个程序猿在使用每一种语言时都会首先想到用于解决并发的工具(JS程序员请回避),使用多线程可以有效的利用CPU资源(Python例外)。然而多线程所带来的程序的复杂度也不可避免,尤其是对竞争资源的同步问题。
然而在python中由于使用了全局解释锁(GIL)的原因,代码并不能同时在多核上并发的运行,也就是说,Python的多线程不能并发,很多人会发现使用多线程来改进自己的Python代码后,程序的运行效率却下降了,这是多么蛋疼的一件事呀!如果想了解更多细节,推荐阅读这篇文章。实际上使用多线程的编程模型是很困难的,程序员很容易犯错,这并不是程序员的错误,因为并行思维是反人类的,我们大多数人的思维是串行(精神分裂不讨论),而且冯诺依曼设计的计算机架构也是以顺序执行为基础的。所以如果你总是不能把你的多线程程序搞定,恭喜你,你是个思维正常的程序猿:)
Python提供两组线程的接口,一组是thread模块,提供基础的,低等级(Low Level)接口,使用Function作为线程的运行体。还有一组是threading模块,提供更容易使用的基于对象的接口(类似于Java),可以继承Thread对象来实现线程,还提供了其它一些线程相关的对象,例如Timer,Lock
使用thread模块的例子
import thread
def worker():
"""thread worker function"""
print 'Worker'
thread.start_new_thread(worker)
使用threading模块的例子
import threading
def worker():
"""thread worker function"""
print 'Worker'
t = threading.Thread(target=worker)
t.start()
或者Java Style
import threading
class worker(threading.Thread):
def __init__(self):
pass
def run():
"""thread worker function"""
print 'Worker'
t = worker()
t.start()
❾ Python编写程序,实现输入n个整数,输出最大的,并指出是第几个数
a=list(eval(input(“请输入n个整数”)))
b=max(a)
c=len(a)
for i in range(1,c+1):
if a[i-1]==b:
print("最大的数是%d,是第%d个数"%(b,i))