python fileinput中的description

本文详细介绍了Python中的fileinput模块,包括其基本用法、常见函数介绍及实例演示。讲解了如何利用该模块处理一个或多个文本文件,进行文件读取、行计数等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


fileinput模块提供处理一个或多个文本文件的功能, 可以通过使用for..in来循环读取一个或多个文本文件内容.

例子中的文件,
1.txt
1a
2a
3a
4a

2.txt
1b
2b
 
DESCRIPTION
   Typical use is:
   
       import fileinput
       for line in fileinput.input():
           process(line)
   
   This iterates over the lines of all files listed in sys.argv[1:],
   defaulting to sys.stdin if the list is empty.  If a filename is '-' it
   is also replaced by sys.stdin.  Tospecify an alternative list of
   filenames, pass it as the argument to input().  A single file name is
   also allowed.
[译]这个迭代了所有文件的行在sys.argv[1:]中,如果列表为空则默认为标准输入,如果文件名为”-”它也为标准输入。指定一个文件名列表来做为参数传递给input,一个单独的文件名也是允许的。
[例]
(1)#!/usr/bin/envpython
importfileinput,sys
 
for line infileinput.input(sys.argv[1:]):
    pass
printfileinput.lineno(),
命令行下,输入python test.py1.txt 2.txt
(2)#!/usr/bin/envpython
import fileinput
 
for line infileinput.input(['1.txt','2.txt']):
    pass
printfileinput.lineno(),
(3) #!/usr/bin/envpython
import fileinput
 
for line infileinput.input(“1.txt”):
    pass
printfileinput.lineno(),
 
   Functions filename(), lineno() return the filename and cumulative line
   number of the line that has just been read; filelineno() returns its
   line number in the current file; isfirstline() returns true iff the
   line just read is the first line of its file; isstdin() returns true
   iff the line was read from sys.stdin. Function nextfile() closes the
   current file so that the next iteration will read the first line from
   the next file (if any); lines not read from the file will not count
   towards the cumulative line count; the filename is not changed until
   after the first line of the next file has been read.  Function close()
   closes the sequence.
[译]函数filename,lineno返回的读取的文件名与已经读的累计的行数;filelineno返回当前文件的行数的函数;如果读的是它自己的文件第一行,那么isfirstline是正确的。如果读的是来自标准输入那么isstdin返回真。函数nextfile关闭当前文件以致下一个迭代器将从下一个文件第一行读起;将不会累计上一个文件的行数.这个文件名不会改变,直到读取下一个文件的第一行。函数close关闭序列。
[例]
(1) #!/usr/bin/envpython
import fileinput
 
for line infileinput.input(['1.txt']):
    pass
printfileinput.filename(),fileinput.lineno()
[root@newpatch3/home/python]#python test.py
1.txt 4
 
(2)   #!/usr/bin/env python
import fileinput   
 
for line infileinput.input(['1.txt','2.txt']):
   pass
printfileinput.filename(),":",fileinput.filelineno()
print "1.txt and 2.txt totalline:",fileinput.lineno()
[root@newpatch3 /home/python]#pythontest.py
2.txt : 2
1.txt and 2.txt total line: 6
大家看到没,filelineno与lineno的差异了吧?
(3) #!/usr/bin/env python
import fileinput,sys
 
for line in fileinput.input([‘1.txt’]):
   if fileinput.isfirstline():
       print line,
       sys.exit(0)
[root@newpatch3 /home/python]#pythontest.py
1a
原1.txt中有1a,2a,3a,4a四行数,但我们通过条件判断,只取第一条,来演示isfirstline功能.
(4) #!/usr/bin/env python
import fileinput
 
for line in fileinput.input():
   if fileinput.isstdin():
       print "isstdin"
[root@newpatch3 /home/python]#pythontest.py
This is stdin
Isstdin
 
   Before any lines have been read, filename() returns None and both line
   numbers are zero; nextfile() has no effect.  After all lines have been
   read, filename() and the line number functions return the values
   pertaining to the last line read; nextfile() has no effect.
[译]没有行读取前,filename返回None和行号为0,nextfile也不起作用。在所有行被读后,filename和获取行号的函数才能返回到已经读的当前行。Nextfile才能起作用。
[例]自己测试。
   All files are opened in text mode. If an I/O error occurs during
   opening or reading a file, the IOError exception is raised.
    [译]所有的文件以文本模式打开,如果在打开或者读一个文件时发生了一个I/O错误,将会产生一个IOError异常。
   If sys.stdin is used more than once, the second and further use will
   return no lines, except perhaps for interactive use, or if it has been
   explicitly reset (e.g. using sys.stdin.seek(0)).
[译]如果标准输入用了多次,第二次将不会返回任何行,除在交互模式下,或者将其重置。
[例]
#!/usr/bin/envpython
import fileinput,sys
 
for line infileinput.input():
    print "line1:",line,
fileinput.close()
sys.stdin.seek(0)
for line infileinput.input():
    print "line2:",line,
fileinput.close()
 
[root@newpatch3/home/python]#python test.py
a
b
c
line1: a
line1: b
line1: c
e
f
g
line2: e
line2: f
line2: g
 
   Empty files are opened and immediately closed; the only time their
   presence in the list of filenames is noticeable at all is when the
   last file opened is empty.
   
   It is possible that the last line of a file doesn't end in a newline
   character; otherwise lines are returned including the trailing
   newline.
   
   Class FileInput is the implementation; its methods filename(),
   lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
   correspond to the functions in the module.  In addition it has a
   readline() method which returns the next input line, and a
   __getitem__() method which implements the sequence behavior.  The
   sequence must be accessed in strictly sequential order; sequence
   access and readline() cannot be mixed.
    [译]类fileinput是这个的实例;它的方法有filename(),….对应的功能在这个模块中。除此之外还有readline方法,返回下一行输入,和__getitem__()方法。 该序列中,必须严格按顺序访问;序例访问和 readline 不能混淆。
   Optional in-place filtering: if the keyword argument inplace=1 is
   passed to input() or to the FileInput constructor, the file is moved
   to a backup file and standard output is directed to the input file.
   This makes it possible to write a filter that rewrites its input file
   in place.  If the keyword argumentbackup=".<some extension>" is also
   given, it specifies the extension for the backup file, and the backup
   file remains around; by default, the extension is ".bak" andit is
   deleted when the output file is closed. In-place filtering is
   disabled when standard input is read. XXX The current implementation
does not workfor MS-DOS 8+3 filesystems.
[译]这段话总的意思是说,inplace如果设为1,那么就将读到的行,输出到输入文件中。如果有backup这个参数,就会将源文件内容输入到备份文件中,输出还会输出到输入文件中。
[例]
(1A)#!/usr/bin/envpython
importfileinput,sys
 
for line infileinput.input("1.txt", inplace=0):
    print line,
[root@newpatch3/home/python]#python test.py
1a
2a
3a
4a
[root@newpatch3 /home/python]#more 1.txt
1a
2a
3a
4a
(1B)   #!/usr/bin/env python
import fileinput,sys
 
for line infileinput.input("1.txt",inplace=1):
print “test”,
[root@newpatch3/home/python]#python test.py
[root@newpatch3/home/python]#more 1.txt
test test testtest
通过1A与1B可以发现,我们如果不指定backup的话,就会将输出直接写入到1.txt文件中。
(2) #!/usr/bin/envpython
importfileinput,sys
 
for line infileinput.input("1.txt",inplace=1,backup=".bak"):
    print "test\n",
[root@newpatch3/home/python]#ls
1.txt       1.txt.bak     2.txt test.py
[root@newpatch3/home/python]#more 1.txt
test
test
test
test
[root@newpatch3/home/python]#more 1.txt.bak
1a
2a
3a
4a
 
   Performance: this module is unfortunately one of the slower ways of
   processing large numbers of input lines. Nevertheless, a significant
   speed-up has been obtained by using readlines(bufsize) instead of
   readline().  A new keywordargument, bufsize=N, is present on the
   input() function and the FileInput() class to override the default
buffer size.

[译]对与处理大量的输入行的处理是不理想的。然而,一个重要的加速已使用readlinesbufsize)来代替ReadLine()。一个新的关键参数,bufsize=N,是在input()函数中存在的和FileInput()类中覆盖buffersize的默认值。总的一句话,通过buffersize这个关键函数可以提高大量的输入。


本文出自 “坏男孩” 博客,请务必保留此出处http://5ydycm.blog.51cto.com/115934/305488


<think>我们有两个主要问题需要解决:1.如何使用Python通过request.form发送数据(非HTML表单)?2.如何解决Flask中JSON序列化错误?首先,关于第一个问题:使用Python发送form数据(非HTML表单)我们可以使用Python的requests库来模拟表单数据的提交。虽然用户提到“非HTML表单”,但这里实际上是指通过程序(而非浏览器)发送类似于HTML表单提交的数据,即application/x-www-form-urlencoded格式的数据。其次,关于第二个问题:FlaskJSON序列化错误这通常是因为在尝试序列化不可JSON序列化的对象(如request.headers对象)导致的。解决方案包括:-避免直接序列化不可序列化的对象,而是提取需要的数据(如将request.headers转换为字典)-或者自定义JSON编码器下面我们分别详细说明。###一、使用Python发送form数据(非HTML表单)使用Python的`requests`库,我们可以很方便地发送form数据。关键点是设置`data`参数(而不是json参数),并设置合适的请求头(虽然requests会自动设置,但有时需要明确)。示例代码:```pythonimportrequestsurl='http://example.com/submit'data={'key1':'value1','key2':'value2'}#发送POST请求,数据以form表单形式发送(application/x-www-form-urlencoded)response=requests.post(url,data=data)#打印响应print(response.text)```如果你需要发送文件,可以使用`files`参数:```pythonfiles={'file':open('report.xls','rb')}response=requests.post(url,files=files,data=data)```###二、解决Flask中的JSON序列化错误在Flask中,当你尝试使用`jsonify`序列化不可序列化的对象时(比如`request.headers`),会抛出`TypeError:Objectoftype...isnotJSONserializable`错误。解决方案如下:####方法1:提取需要的数据,避免直接序列化不可序列化的对象例如,不要直接序列化`request.headers`,而是将其转换为字典:```pythonfromflaskimportFlask,request,jsonifyapp=Flask(__name__)@app.route('/submit',methods=['POST'])defsubmit():#获取表单数据form_data=request.form.to_dict()#获取请求头,但只取部分或转换为字典headers_data=dict(request.headers)#注意:如果请求头中有敏感信息,应该过滤#例如,只取Content-Type#headers_data={'Content-Type':request.headers.get('Content-Type')}#返回的数据中只包含可序列化的对象returnjsonify({'form_data':form_data,'headers':headers_data})```####方法2:自定义JSON编码器如果你确实需要序列化一些特殊对象,可以自定义JSON编码器。例如,处理`Headers`对象:```pythonfromflaskimportFlask,request,jsonifyfromflask.jsonimportJSONEncoderfromwerkzeug.datastructuresimportHeadersclassCustomJSONEncoder(JSONEncoder):defdefault(self,obj):ifisinstance(obj,Headers):returndict(obj)returnsuper().default(obj)app=Flask(__name__)app.json_encoder=CustomJSONEncoder@app.route('/submit',methods=['POST'])defsubmit():#现在可以直接序列化request.headers了returnjsonify({'form_data':request.form.to_dict(),'headers':request.headers})```###三、综合示例:发送form数据并避免序列化错误假设我们有一个Flask服务,接收form数据,并返回接收到的数据以及部分请求头信息(避免敏感信息)。**Flask服务端代码:**```pythonfromflaskimportFlask,request,jsonifyapp=Flask(__name__)@app.route('/api/submit',methods=['POST'])defhandle_submit():#获取表单数据(字典形式)form_data=request.form.to_dict()#选择性获取请求头信息,避免暴露敏感信息safe_headers={'Content-Type':request.headers.get('Content-Type'),'User-Agent':request.headers.get('User-Agent')}#返回JSON响应returnjsonify({'status':'success','form_data':form_data,'headers':safe_headers})if__name__=='__main__':app.run(debug=True)```**客户端发送form数据的Python代码:**```pythonimportrequestsurl='http://127.0.0.1:5000/api/submit'data={'name':'Alice','email':'alice@example.com'}response=requests.post(url,data=data)print(response.json())```###注意事项:1.**敏感信息**:在返回请求头信息时,避免返回如`Cookie`、`Authorization`等敏感头。2.**文件上传**:如果客户端需要上传文件,则服务端应使用`request.files`获取文件。3.**调试模式**:在开发时可以使用`debug=True`,但生产环境应关闭[^1]。###常见问题解答:**Q:为什么使用`request.form`获取数据?**A:因为客户端发送的是form表单数据(application/x-www-form-urlencoded),所以使用`request.form`获取。如果是JSON数据,则使用`request.json`。**Q:如何发送JSON数据?**A:客户端应设置`Content-Type:application/json`,并将数据作为`json`参数传递给requests.post:```pythonresponse=requests.post(url,json=data)```服务端则使用`request.json`来获取数据。###相关问题:1.如何安全地从Flask请求头中提取特定信息而不暴露敏感数据?2.在Flask中如何处理文件上传?3.如何区分Flask中的`request.form`和`request.json`?4.如何优化Flask应用的JSON响应性能?希望以上解答能帮助你解决问题。</think>### 使用Python通过`request.form`发送数据(非HTML表单)及解决Flask序列化错误 #### 一、Python发送form数据的核心方法 使用Python的`requests`库可以模拟form表单提交,无需HTML表单: ```python import requests # 1. 基本form数据提交 url = 'http://your-flask-server.com/submit' form_data = { 'username': 'test_user', 'password': 'secure_pass123', 'action': 'login' } response = requests.post(url, data=form_data) # 使用data参数而非json print(response.json()) # 2. 文件上传 + 表单数据 files = {'file': open('document.pdf', 'rb')} form_data_with_file = { 'description': '重要文件', 'category': 'finance' } response = requests.post(url, data=form_data_with_file, files=files) ``` #### 二、Flask端接收与序列化错误解决方案 在Flask中正确处理请求并避免序列化错误: ```python from flask import Flask, request, jsonify from werkzeug.datastructures import ImmutableMultiDict app = Flask(__name__) @app.route('/submit', methods=['POST']) def handle_form(): # 正确获取form数据(自动处理ImmutableMultiDict) form_data = request.form.to_dict() # 转换为普通字典[^3] # 解决序列化错误的三种方法 # 方法1:直接使用可序列化字典 result = { 'status': 'success', 'user': form_data.get('username'), 'action': form_data.get('action') } # 方法2:过滤敏感头信息 safe_headers = { 'Content-Type': request.headers.get('Content-Type'), 'User-Agent': request.headers.get('User-Agent') } # 方法3:自定义JSON编码器(处理特殊类型) class SafeEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, ImmutableMultiDict): return dict(obj) return super().default(obj) return jsonify({ 'form_data': form_data, 'safe_headers': safe_headers }), 200, {'Content-Type': 'application/json; charset=utf-8'} ``` #### 三、常见错误场景与解决方案 | 错误类型 | 原因 | 解决方案 | |---------|------|---------| | `TypeError: Object of type ImmutableMultiDict...` | 直接序列化`request.form` | 使用`.to_dict()`转换 | | 暴露敏感头信息 | 完整返回`request.headers` | 选择性提取关键头 | | 文件上传失败 | 未正确处理`request.files` | 分开处理文件和表单数据 | #### 四、高级场景:AJAX与Flask交互 使用AJAX发送form数据并处理响应: ```javascript // JavaScript前端代码 const formData = new FormData(); formData.append('username', 'ajax_user'); formData.append('file', fileInput.files[0]); fetch('/flask-api', { method: 'POST', body: formData // 自动设置multipart/form-data }) .then(response => response.json()) .then(data => console.log(data)); ``` ```python # Flask处理AJAX请求 @app.route('/flask-api', methods=['POST']) def api_endpoint(): # 同时处理表单数据和文件 form_data = request.form.to_dict() uploaded_file = request.files['file'] # 处理文件保存等操作 uploaded_file.save(f"/uploads/{form_data['username']}.pdf") return jsonify({ 'message': '文件上传成功', 'metadata': form_data }) ``` #### 五、最佳实践建议 1. **数据转换**:始终使用`.to_dict()`处理`request.form`[^3] 2. **头信息过滤**:避免返回完整头信息,只暴露必要字段 3. **错误处理**:添加全局异常捕获 ```python @app.errorhandler(TypeError) def handle_serialization_error(e): return jsonify(error="序列化失败", detail=str(e)), 500 ``` 4. **内容协商**:明确设置响应头`Content-Type`[^2] 5. **调试模式**:开发时启用`debug=True`但生产环境务必关闭[^1] > **关键点**:Flask的`request.form`本质是`ImmutableMultiDict`类型,通过`.to_dict()`转换为标准字典可彻底解决序列化问题。对于复杂场景,建议结合自定义JSON编码器[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值