51. 字符串格式化方式
1. 使用 % 操作符
print("This is for %s" % "Python") print("This is for %s, and %s" %("Python", "You"))
output
This is for Python This is for Python, and You
2. str.format
在 Python3 中,引入了这个新的字符串格式化方法。
print("This is my {}".format("chat")) print("This is {name}, hope you can {do}".format(name="zhouluob", do="like"))
output
This is my chat This is zhouluob, hope you can like
3. f-strings
在 Python3-6 中,引入了这个新的字符串格式化方法。
name = "luobodazahui" print(f"hello {name}")
output
hello luobodazahui
一个复杂些的例子:
def mytest(name, age): return f"hello {name}, you are {age} years old!" people = mytest("luobo", 20) print(people)
output
hello luobo, you are 20 years old!
52. 将"hello world"转换为首字母大写"Hello World"(不使用 title 函数)
str1 = "hello world" print(str1.title()) " ".join(list(map(lambda x: x.capitalize(), str1.split(" "))))
output
Hello World 'Hello World'
53. 一行代码转换列表中的整数为字符串
如:[1, 2, 3] -> ["1", "2", "3"]
list1 = [1, 2, 3] list(map(lambda x: str(x), list1))
output
['1', '2', '3']
54. 合并两个元组到字典
如:("zhangfei", "guanyu"),(66, 80) -> {'zhangfei': 66, 'guanyu': 80}
a = ("zhangfei", "guanyu") b = (66, 80) dict(zip(a,b))
output
{'zhangfei': 66, 'guanyu': 80}
55. 给出如下代码的输入,并简单解释
例子1:
a = (1,2,3,[4,5,6,7],8) a[3] = 2
output
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-35-59469d550eb0> in <module> 1 a = (1,2,3,[4,5,6,7],8) ----> 2 a[3] = 2 3 #a TypeError: 'tuple' object does not support item assignment
例子2:
a = (1,2,3,[4,5,6,7],8) a[3][2] = 2 a
output
(1, 2, 3, [4, 5, 2, 7], 8)
从例子1的报错中也可以看出,tuple 是不可变类型,不能改变 tuple 里的元素,例子2中,list 是可变类型,改变其元素是允许的。
56. Python 中的反射
反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
简单理解就是用来判断某个字符串是什么,是变量还是方法
class NewClass(object): def __init__(self, name, male): self.name = name self.male = male def myname(self): print(f'My name is {self.name}') def mymale(self): print(f'I am a {self.male}') people = NewClass('luobo', 'boy') print(hasattr(people, 'name')) print(getattr(people, 'name')) setattr(people, 'male', 'girl') print(getattr(people, 'male'))
output
True luobo girl
getattr,hasattr,setattr,delattr 对模块的修改都在内存中进行,并不会影响文件中真实内容。
57. 实现一个简单的 API
使用 flask 构造 web 服务器
from flask import Flask, request app = Flask(__name__) @app.route('/', methods=['POST']) def simple_api(): result = request.get_json() return result if __name__ == "__main__": app.run()
58. metaclass 元类
类与实例:
首先定义类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
类与元类:
先定义元类, 根据 metaclass 创建出类,所以:先定义 metaclass,然后创建类。
class MyMetaclass(type): def __new__(cls, class_name, class_parents, class_attr): class_attr['print'] = "this is my metaclass's subclass %s" %class_name return type.__new__(cls, class_name, class_parents, class_attr) class MyNewclass(object, metaclass=MyMetaclass): pass myinstance = MyNewclass() myinstance.print
output
"this is my metaclass's subclass MyNewclass"
59. sort 和 sorted 的区别
sort() 是可变对象列表(list)的方法,无参数,无返回值,sort() 会改变可变对象.
dict1 = {'test1':1, 'test2':2} list1 = [2, 1, 3] print(list1.sort()) list1
output
None [1, 2, 3]
sorted() 是产生一个新的对象。sorted(L) 返回一个排序后的L,不改变原始的L。sorted() 适用于任何可迭代容器。
dict1 = {'test1':1, 'test2':2} list1 = [2, 1, 3] print(sorted(dict1)) print(sorted(list1))
output
['test1', 'test2'] [1, 2, 3]
60. Python 中的 GIL
GIL 是 Python 的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行 Python 程序的时候会占用 Python 解释器(加了一把锁即 GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
61. 产生8位随机密码
import random "".join(random.choice(string.printable[:-7]) for i in range(8))
output
'd5^NdNJp'
62. 输出原始字符
print('hello\nworld') print(b'hello\nworld') print(r'hello\nworld')
output
hello world b'hello\nworld' hello\nworld
63. 列表内,字典按照 value 大小排序
list1 = [{'name': 'guanyu', 'age':29}, {'name': 'zhangfei', 'age': 28}, {'name': 'liubei', 'age':31}] sorted(list1, key=lambda x:x['age'])
output
[{'name': 'zhangfei', 'age': 28}, {'name': 'guanyu', 'age': 29}, {'name': 'liubei', 'age': 31}]
64. 简述 any() 和 all() 方法
all 如果存在 0 Null False 返回 False,否则返回 True;any 如果都是 0,None,False,Null 时,返回 True。
print(all([1, 2, 3, 0])) print(all([1, 2, 3])) print(any([1, 2, 3, 0])) print(any([0, None, False]))
output
False True True False
65. 反转整数
def reverse_int(x): if not isinstance(x, int): return False if -10 < x < 10: return x tmp = str(x) if tmp[0] != '-': tmp = tmp[::-1] return int(tmp) else: tmp = tmp[1:][::-1] x = int(tmp) return -x reverse_int(-23837)
output
-73832
首先判断是否是整数,再判断是否是一位数字,最后再判断是不是负数
66. 函数式编程
函数式编程是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。由于 Python 允许使用变量,因此,Python 不是纯函数式编程语言。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
函数作为返回值例子:
def sum(*args): def inner_sum(): tmp = 0 for i in args: tmp += i return tmp return inner_sum mysum = sum(2, 4, 6) print(type(mysum)) mysum()
output
<class 'function'> 12
67. 简述闭包
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
附上函数作用域图片
闭包特点
1.必须有一个内嵌函数
2.内嵌函数必须引用外部函数中的变量
3.外部函数的返回值必须是内嵌函数
68. 简述装饰器
装饰器是一种特殊的闭包,就是在闭包的基础上传递了一个函数,然后覆盖原来函数的执行入口,以后调用这个函数的时候,就可以额外实现一些功能了。
一个打印 log 的例子:
import time def log(func): def inner_log(*args, **kw): print("Call: {}".format(func.__name__)) return func(*args, **kw) return inner_log @log def timer(): print(time.time()) timer()
output
Call: timer 1560171403.5128365
本质上,decorator就是一个返回函数的高阶函数
69. 协程的优点
子程序切换不是线程切换,而是由程序自身控制
没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显
不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁
70. 实现一个斐波那契数列
斐波那契数列:
又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
生成器法:
def fib(n): if n == 0: return False if not isinstance(n, int) or (abs(n) != n): # 判断是正整数 return False a, b = 0, 1 while n: a, b = b, a+b n -= 1 yield a [i for i in fib(10)]
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
递归法:
def fib(n): if n == 0: return False if not isinstance(n, int) or (abs(n) != n): return False if n <= 1: return n return fib(n-1)+ fib(n-2) [fib(i) for i in range(1, 11)]
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]