9.python的用户交互

it2023-02-11  47

在程序中,我们经常能够遇到需要用户输入,或者程序输出的情况,这种情况被统称为用户交互


接收用户输入

username = input("请输入您的账号:")

在python3中input功能会等待用户的输入,括号里的内容作用是起到提示作用,用户输入任何内容,都存成字符串类型,然后赋值给等号左边的变量名

username = input("请输入你的账号:") # 程序就会在这里暂停,然后等待用户输入 print(username) # 输出结果(用户输入kinght) # 请输入你的账号:kinght # kinght

类型转换简介

前面说到,input接收到的内容全都是字符串形式,但是字符串形式有些功能并不好参与

例如:现在要判断一个人是否成年?输入了他的年龄要与18进行比较,可字符串形式并不能直接进行比较

age = input("请输入年龄:") age = int(age) # 将age转换为int类型(int只能将纯数字的字符串转为整型) print(age >= 18)

了解知识:

1、在python2中存在一个raw_input功能与python3中的input功能一模一样

2、在python2中还存在一个input功能,需要用户输入一个明确的数据类型,输入什么类型就存成什么类型

#python2环境 age = input('python2测试:') #输入 print(type(age)) #输出 #输入123,输出结果为<type 'int'> #输入'abc',输出结果为<type 'str'> #输入3.14,输出结果为<type 'float'> #输入成什么类型,python2即保存为什么类型

但python2所带来的后果就是用户的输入不可控,鬼知道会输入什么乱七八糟的东西导致程序错误


格式化输出

输出我们已经接触过,就是print,所谓格式化输出,即为提前规定好输出的格式

%号格式

%号格式化字符串的方式从Python诞生之初就已经存在,时至今日,python官方也并未弃用%号,但也并不推荐这种格式化方式。

# 1、格式的字符串(即%s)与被格式化的字符串(即传入的值)必须按照位置一一对应 # ps:当需格式化的字符串过多时,位置极容易搞混 print("my name is %s , my age is %s" %('kinght',22)) # 2、可以通过字典方式格式化,打破了位置带来的限制与困扰 print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % {'name': 'kinght', 'age': 22}) kwargs={'name': 'kinght', 'age': 22} print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % kwargs)

str.format(推荐使用)

该format方法是在Python 2.6中引入的,是字符串类型的内置方法。因为str.format的方式在性能和使用的灵活性上都比%号更胜一筹,所以推荐使用

# 按照位置一一对应 print("{} likes {}".format('kinght','AYM')) # 使用索引取对应位置的值({序号}对应format序号) print('{0}{2}{1}{0}'.format('A','B','C')) # ACBA # 可以通过关键字or字典方式的方式格式化,打破了位置带来的限制与困扰({关键字}=值) print('我的名字是 {name}, 我的年龄是 {age}.'.format(age=22, name='kinght')) kwargs = {'name': 'kinght', 'age': 22} # 字典 print('我的名字是 {name}, 我的年龄是 {age}.'.format(**kwargs)) # 使用字典key进行索引 # 先取到值,然后在冒号后设定填充格式: # {0:[填充字符][对齐方式][宽度]} # 0为取值位置 # *<10:左对齐,总共10个字符,不够的用*号填充 print('{0:*<10}'.format('开始执行')) # 开始执行****** # *>10:右对齐,总共10个字符,不够的用*号填充 print('{0:*>10}'.format('开始执行')) # ******开始执行 # *^10:居中显示,总共10个字符,不够的用*号填充 print('{0:*^10}'.format('开始执行')) # ***开始执行*** # 精度输出 print('{salary:.3f}'.format(salary=3.14159264735)) #精确到小数点后3位,四舍五入,结果为:3.142 print('{0:,}'.format(99812939393931)) # 千分位格式化,结果为:99,812,939,393,931 # 进制输出 print('{0:b}'.format(123)) # 转成二进制,结果为:1111011 print('{0:o}'.format(9)) # 转成八进制,结果为:11 print('{0:x}'.format(15)) # 转成十六进制,结果为:f

f-Strings

str.format() 比 %格式化高级了一些,但是它还是有自己的缺陷。当需要传入的字符串过多时,仍然会显得非常冗长。与在Python 3.6中引入 了f-strings,不仅比str.format更简洁,性能上也更胜一筹

f-string是以f或F开头的字符串, 核心在于字符串中符号{}的使用

# {}中可以是变量名 name = 'kinght' age = 22 print(f'{name} {age}') # kinght 22 print(F'{age} {name}') # 22 kinght # {}中可以是表达式 # 可以在{}中放置任意合法的Python表达式,会在运行时计算 # 比如:数学表达式 print(f'{3*3/2}') # 4.5 # 函数的调用 def foo(n): print('foo say hello') return n print(f'{foo(10)}') # 会调用foo(10),然后打印其返回值 # 调用对象的方法 name='kinght' print(f'{name.lower()}') # kinght # 在类中的使用 >>> class Person(object): ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __str__(self): ... return f'{self.name}:{self.age}' ... def __repr__(self): ... return f'===>{self.name}:{self.age}<===' ... >>> >>> obj=Person('kinght',18) >>> print(obj) # 触发__str__ egon:18 >>> obj # 触发__repr__ ===>kinght:18<=== >>> >>> >>> >>> # 在f-Strings中的使用 >>> f'{obj}' # 触发__str__ 'egon:18' >>> f'{obj!r}' # 触发__repr__ '===>kinght:18<===' # 当格式化字符串过长时,如下列表info name = 'kinght' age = 18 gender = 'male' hobbie1='play' hobbie2='eat' hobbie3='read' info = [f'名字:{name}年龄:{age}性别:{gender}',f'第一个爱好:{hobbie1}第二个爱好:{hobbie2}第三个爱好:{hobbie3}'] # 我们可以回车分隔到多行,注意每行前都有一个f info = [ # 第一个元素 f'名字:{name}' f'年龄:{age}' f'性别:{gender}', # 第二个元素 f'第一个爱好:{hobbie1}' f'第二个爱好:{hobbie2}' f'第三个爱好:{hobbie3}' ] print(info) # ['名字:kinght年龄:18性别:male', '第一个爱好:play第二个爱好:eat第三个爱好:read'] ### 引号的嵌套 # 当字符串嵌套发送冲突时,与正常的字符串处理方式是一样的 # 1、外层为单引号,内层嵌套也为单引号,并且想要输入的内容也为单引号,那么外层需要改用双引号 print("my name is 'kinght'") # 2、外层为单引号,内层嵌套也为单引号,并且想要输入的内容也为单引号,需要用到转义 print('my name is \'kinght\'')

注意

###注意 #1、反斜杠可以用来进行字符转义,但不能用在{}的表达式中 f'{1\2}' # 语法错误 #2、注释#号也不能出现在{}的表达式中 f'{x#}' # 语法错误 #基于注意,不能在{}内出现反斜杠\,所以,当我们的输出的结果中需要包含{}时,下面的做法就是错误的 print(f'\{天王盖地虎\}') # 错误 #类似于输出%号的做法 print('%s%%' %30) 30% #若想输出{},那么需要在原有的基础上再套一层,如下 print(f'{{天王盖地虎}}') # {天王盖地虎} print(f'{{{{天王盖地虎}}}}') # {{天王盖地虎}} ### 性能对比=>f_Stings性能最高 from timeit import timeit def test_s(): name = 'Egon' age = 18 return '%s:%s.' % (name, age) def test_format(): name = 'Egon' age = 18 return '{}:{}.'.format(name, age) def test_f_strings(): name = 'Egon' age = 18 return f'{name}:{age}.' res1 = timeit(test_s, number=1000000) res2 = timeit(test_format, number=1000000) res3 = timeit(test_f_strings, number=1000000) print(res1) # 0.3709844550030539 print(res2) # 0.47834375899401493 print(res3) # 0.3111891380031011, 最快

标准库模板

从Python 2.4起,Python标准库string引入了Template也可以用来格式化字符串,所以说,与前三种方式的一个显著区别就是:Template并属于python语言的核心语法特征,使用方式如下

from string import Template name='kinght' t = Template('Hello $name!') res=t.substitute(name=name) print(res) # Hello kinght!

另外一个不同的地方是这个模板字符串不支持类似str.format那样的进制转换,需要我们自己处理

from string import Template name='kinght' templ_string = 'Hello $name, there is a $error error!!!' res=Template(templ_string).substitute(name=name, error=hex(12345)) print(res) # Hello kinght, there is a 0x3039 error!!!

使用模板字符串Template的最佳的时机就是当你的程序需要处理由用户提供的输入内容时。模板字符串是最保险的选择,因为可以降低复杂性。

其他一些复杂的字符串格式化技巧的可能会给你的程序带来安全漏洞

总结四种方式的应用场景

1、如果格式化的字符串是由用户输入的,那么基于安全性考虑,推荐使用Template

2、如果使用的python3.6+版本的解释器,推荐使用f-Stings

3、如果要兼容python2.x版本的python解释器,推荐使用str.format

4、如果不是测试的代码,不推荐使用%

print补充知识

在python中,使用print的时候,会默认添加换行符,我们可以通过添加end=''的形式将添加的换行符替换掉,来阻止换行

print('hello',end='') print('world')

也可以进行其他替换

print('hello',end='*') print('world') #hello*world

at

4、如果不是测试的代码,不推荐使用%

print补充知识

在python中,使用print的时候,会默认添加换行符,我们可以通过添加end=''的形式将添加的换行符替换掉,来阻止换行

print('hello',end='') print('world')

[外链图片转存中…(img-u6TcTZRl-1603172774861)]

也可以进行其他替换

print('hello',end='*') print('world') #hello*world
最新回复(0)