我正在创建一个Python脚本,要求输入命令行。用户可以编辑文件的一部分。我可以要求提供新信息并在文件中覆盖它,没问题。但我宁愿将文件的编辑部分放在命令行中,因此不必完全输入。这可能吗?
文件:
1|This file
2|is not empty
示例:
>>>edit line 2
Fetching line 2
Edit the line then hit enter
>>>is not empty #This is written here by the script, not by the user
然后可以改为
>>>is not full either
Edited file
该文件已更改为:
1|This file
2|is not full either
我希望它能清楚我要完成的任务。
已经说过{p> This问题可以回答我的问题,它确实在一定程度上。当我使用readline
运行Linux时,它会这样做。但是,我不是。我使用的是Windows而我没有使用readline
。我想只使用标准库。ImportError
win32console
,可能是因为提到的问题不是关于Python3.4,而是我的问题。
另外,我想知道这是否可能使用标准库,而不是外部库。
答案 0 :(得分:1)
不幸的是,我不知道标准库中是否有input()
类型的默认值。
有一个外部解决方案 - 使用this answer中提到的win32console
。然而,就我所见,它有两个陷阱。 首先,导入捆绑在包pywin32中。所以你会使用pip install pywin32
,但它不起作用,因为第二个陷阱:有关pypi包的信息已经过时,它说包与Python 3.4不兼容。
但事实上,它可以工作!您应该按照pypi项目页面上显示的“下载URL”(即https://sourceforge.net/projects/pywin32/files/pywin32/)并安装最新版本。我刚为Py3.4安装了build 219,因为我自己也使用这个Python版本。在页面安装程序上提供了几个适用于32位和64位Windows的Python版本。
另外,我已经调整了上面链接的SO代码的代码,以便在Python 3中工作:
import win32console
_stdin = win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
def input_def(prompt, default=''):
keys = []
for c in str(default):
evt = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
evt.Char = c
evt.RepeatCount = 1
evt.KeyDown = True
keys.append(evt)
_stdin.WriteConsoleInput(keys)
return input(prompt)
if __name__ == '__main__':
name = input_def('Folder name: ', 'it works!!!')
print()
print(name)
这适用于我的Windows机器......如果这对你的机器不起作用,你能提供错误信息吗?
答案 1 :(得分:1)
我写过一个行编辑器,希望能够满足您的需求。但这是一个快速而肮脏的黑客。它仅适用于Windows,在Windows 10上使用CPython 3.6.5编写,因此其使用可能有限。它已经在代码页1252(ANSI Latin 1;西欧(Windows))和代码页65001(utf-8)上进行了测试。由于没有速度优化,它非常基本且有点迟缓。 (我应该用C重写它,但我没有时间。)它几乎没有经过测试和记录不足。
import msvcrt
import os
import sys
if os.name != 'nt':
raise NotImplementedError('This module works only on MS Windows!')
CTRL_00 = 0
CTRL_E0 = 224
KEY_BACKSPACE = 8
KEY_DELETE = 83 # CTRL
KEY_END = 79 # CTRL
KEY_ESC = 27
KEY_HOME = 71 # CTRL
KEY_INSERT = 82 # CTRL
KEY_LEFT = 75 # CTRL
KEY_RETURN = 13
KEY_RIGHT = 77 # CTRL
flush = sys.stdout.flush
write = sys.stdout.write
mode = ('[OVR]> ', '[INS]> ') # overwrite, insert
prefix = len(mode[0])
def _update_line(insert, source, length, line, target):
"""Write a new line and position the cursor.
source: previous cursor position
length: old line length
line: edited line
target: next cursor position
"""
write('\b' * source) # set cursor to start of line
write(' ' * length) # erase old line
write('\b' * length) # again, set cursor to start of line
write(mode[insert] + line[prefix:]) # write updated line
write('\b' * (len(line) - target)) # set cursor to new position
flush() # write buffer to screen
def mswin_line_edit(default_string, insert=True):
"""Edit a MS Windows CLI line."""
insert = insert
line = mode[insert] + default_string
count = len(line)
before = line[:count]
after = line[count:]
print(line, end='', flush=True)
cursor = count
while True:
key = msvcrt.getwch()
num = ord(key)
if num == KEY_ESC: # abort edit
return default_string
if num == KEY_RETURN: # finish edit
return line
if num == KEY_BACKSPACE: # delete character before cursor
if cursor > prefix:
before = line[:cursor - 1]
after = line[cursor:]
line = before + after
_update_line(insert, cursor, count, line, cursor - 1)
cursor -= 1
count = len(line)
elif num == CTRL_E0 or num == CTRL_00: # CTRL
ctrl = ord(msvcrt.getwch())
if ctrl == KEY_END: # set cursor after last character
if cursor < count:
before = line
after = ''
_update_line(insert, cursor, count, line, count)
cursor = count
elif ctrl == KEY_HOME: # set cursor before first character
if cursor > prefix:
before = ''
after = line
_update_line(insert, cursor, count, line, prefix)
cursor = prefix
elif ctrl == KEY_LEFT: # move cursor 1 character to the left
if cursor > prefix:
before = line[:cursor]
after = line[cursor:]
_update_line(insert, cursor, count, line, cursor - 1)
cursor -= 1
elif ctrl == KEY_RIGHT: # move cursor 1 character to the right
if cursor < count:
before = line[:cursor]
after = line[cursor:]
_update_line(insert, cursor, count, line, cursor + 1)
cursor += 1
elif ctrl == KEY_DELETE: # delete character after cursor
if cursor < count:
before = line[:cursor]
after = line[cursor + 1:]
line = before + after
_update_line(insert, cursor, count, line, cursor)
count = len(line)
elif ctrl == KEY_INSERT: # switch insert/overwrite mode
insert ^= True
_update_line(insert, cursor, count, line, cursor)
else: # ordinary character
before = line[:cursor] + key
if insert:
after = line[cursor:]
else:
after = line[cursor + 1:]
line = before + after
_update_line(insert, cursor, count, line, cursor + 1)
cursor += 1
count = len(line)
if __name__ == '__main__':
test_string = input('test string: ')
result = mswin_line_edit(test_string)
print(f'\n{result}')
答案 2 :(得分:0)
你可以用tkinter做到这一点:
from tkinter import *
def enter():
global commandEntry
command = commandEntry.get()
# Do stuff with command
commandEntry.delete(0, END)
def edit_line(line):
global commandEntry
commandEntry.insert(0, line)
root = Tk()
messageVar = StringVar()
messageVar.set("Enter a command:")
message = Label(root, textvariable=messageVar)
commandEntry = Entry(root)
enterButton = Button(root, text="Enter", command=enter)
root.mainloop()
答案 3 :(得分:-1)
你应该只有2个变量:一个用于标准字符串,一个用于字符串,用户可以自行更改。 像:
str1 = 'String that is standard'
str2 = str1 #it usually will be standard string
usr = input('your text goes here')
if len(usr) != 0:
str2 = usr
#and here goes code for writing string into file