第一部分 Python基础篇
简述解释型和编译型编程语言?
计算机不理解高级语言,任何高级语言想要被计算机运行,都必须通过转换器(解释器或编译器)转换成计算机语言。
转换方式有两种编译和解释,由此高级语言也分为编译型语言和解释型语言,主要区别在于编译型是源程序编译后可在平台上运行,解释型是在运行期间才编译会有点慢,所以前者运行速度快,后者跨平台性好
Python解释器种类以及特点?
CPython:由C语言开发的python解释器,也是标准的python解释器,是使用最广泛的python解释器。
JPython:运行在Java上的解释器。可以将python源码编译成JVM字节码,由JVM执行对应的字节码,因为可以很好的与JVM集成。
IPython:是基于Cpython之上的一个交互式解释器。
请至少列举5个 PEP8 规范(越多越好)
代码编排:
1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
3 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
文档编排:
1 模块内容的顺序:模块说明和docstring—import—globals&constants—其他定义。其中import部分,又按标准、三方和自己编写顺序依次排放,之间空一行。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/05/17 10:46 # @Author : MJay_Lee # @File : tcp_server.py # @Contact : [email protected] import os import sys from tcp_server import online_user from threading import currentThread from lib import common from interface import common_interface, admin_interface, user_interface conn_pool = ThreadPoolExecutor(10) # 互斥锁为了限制多个线程同时登录一个ID时进行写操作带来的误区 mutex = Lock() # 之所以把mutex放在online_user.py文件中,是因为避免文件的交叉引用 online_user.mutex = mutex def foo1 def foo2View Code
2 不要在一句import中多个库,比如import os, sys不推荐。
3 如果采用from XX import XX引用库,可以省略‘module.’,都是可能出现命名冲突,这时就要采用import XX。
from myclass import MyClass from foo.bar.yourclass import YourClass # 如果和本地名字有冲突: import myclass import foo.bar.yourclassView Code
空格的使用:
(总体原则 避免不必要的空格)
注释:
(总体原则 英文 简明)
- 与代码自相矛盾的注释比没注释更差。修改代码时要优先更新注释!
- 注释是完整的句子。如果注释是断句,首字母应该大写,除非它是小写字母开头的标识符(永远不要修改标识符的大小写)。
- 如果注释很短,可以省略末尾的句号。注释块通常由一个或多个段落组成。段落由完整的句子构成且每个句子应该以点号(后面要有两个空格)结束,并注意断词和空格。
- 非英语国家的程序员请用英语书写你的注释,除非你120%确信代码永远不会被不懂你的语言的人阅读。
- 注释块通常应用在代码前,并和这些代码有同样的缩进。每行以 '# '(除非它是注释内的缩进文本,注意#后面有空格)。注释块内的段落用仅包含单个 '#' 的行分割。
- 慎用行内注释(Inline Comments) 节俭使用行内注释。 行内注释是和语句在同一行,至少用两个空格和语句分开。行内注释不是必需的,重复罗嗦会使人分心。不要这样做:
# 正确写法 x = x + 1 # Compensate for border # 错误写法 x = x + 1 # do nothingView Code
命名:
(总体原则,新编代码必须按下面命名风格进行,现有库的编码尽量保持风格。)
- b(单个小写字母)
- B(单个大写字母)
- lowercase(小写串)
- lower_case_with_underscores(带下划线的小写)
- UPPERCASE(大写串)
- UPPER_CASE_WITH_UNDERSCORES(带下划线的大写串)
- CapitalizedWords(首字母大写的单词串或驼峰缩写)
- 类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
- mixedCase(混合大小写,第一个单词是小写)
- Capitalized_Words_With_Underscores(带下划线,首字母大写,丑陋)
编码建议:
1 编码中考虑到其他python实现的效率等问题,比如运算符‘+’在CPython(Python)中效率很高,都是Jython中却非常低,所以应该采用.join()的方式。
2 尽可能使用‘is’‘is not’取代‘==’,比如if x is not None 要优于if x。
3 使用基于类的异常,每个模块或包都有自己的异常类,此异常类继承自Exception。
4 异常中不要使用裸露的except,except后跟具体的exceptions。
5 异常中try的代码尽可能少。比如:
try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value) 要优于 try: return handle_value(collection[key]) except KeyError: # Will also catch KeyError raised by handle_value() return key_not_found(key)View Code
6 使用startswith() and endswith()代替切片进行序列前缀或后缀的检查。
7 使用isinstance()比较对象的类型。比如
Yes: if isinstance(obj, int): 优于 No: if type(obj) is type(1):View Code
8 判断序列空或不空,有如下规则
Yes: if not seq: if seq:
优于
No: if len(seq) if not len(seq)
9 字符串不要以空格收尾。
10 二进制数据判断使用 if boolvalue的方式。
通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
v2 = int(v,base = 2)
十进制转换成二进制:v = 18
v10 = bin(v)
八进制转换成十进制:v = “011”
v8 = int(v,base = 8)
十进制转换成八进制:v = 30
v10 = oct(v)
十六进制转换成十进制:v = “0x12”
v16 = int(v,base = 16)
十进制转换成十六进制:v = 87
v10 = hex(v)
python递归的最大层数?
Python的最大递归层数是可以设置的,默认的在window上的最大递归层数是 998。
可以通过sys.setrecursionlimit()进行设置,但是一般默认不会超过3925-3929这个范围。
求结果:加减乘除 > 比较 > not and or。(绝招:加括号)
v1 = 1 or 3
# 1
v2 = 1 and 3
# 3
v3 = 0 and 2 and 1 # 0
v4 = 0 and 2 or 1 # 1
v5 = 0 and 2 or 1 or 4 # 1
v6 = 0 or False and 1 # False
ascii、unicode、utf-8、gbk 区别?
它们本质上都是字符与二进制的关系对照表,都维护这自己的一套规则,使用的不同的编码保存文件时,硬盘的文件中存储的0/1的规则也是不同的。以某个编码的形式进行保存文件,以后就要以这种编码去打开这个文件。否则就会出现乱码。
汉字,用gbk编码需要用2个字节;用utf-8编码需要用3个字节。
目前最广泛的编码为:utf-8,他可以表示所有的字符且存储或网络传输也不会浪费资源(对unicode字符集的码位进行压缩了)
字符串类型(str),在程序中用于表示文字信息,本质上是unicode编码中的二进制。
字节类型(bytes)可表示文字信息,本质上是utf-8/gbk等编码的二进制(对unicode进行压缩,方便文件存储和网络传输。)
默认Python解释器是以UTF-8编码的形式打开文件。
如果想要修改Python的默认解释器编码:# -*- coding:gbk -*-
字节码和机器码的区别?
机器码是电脑 CPU 直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写
字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
三元运算规则以及应用场景?
三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值格式
结果 = 条件成立取值 if 条件 else 条件不成立取值
列举常见的内置函数?
map()
map()根据提供的function(函数)对指定的iterable(一个或多个序列可迭代对象( 列表 元组 字典))做映射。
map()函数的语法是:
map(function,iterable,……)
它的结果是返回值一个列表(注意python2是列表,python3是迭代器)
这个函数的意义是将function应用于iterable的每一个元素,结果以列表的形式返回((注意python2是列表,python3是迭代器))
>>> def square(x) : # 计算平方数 ... return x ** 2>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方 [1, 4, 9, 16, 25] >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数 [1, 4, 9, 16, 25]
reduce()
reduce() 函数会对参数序列中元素进行累积。
reduce() 函数语法:
reduce(function, iterable[, initializer])
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
Python3.x reduce() 已经被移到 functools 模块里,如果我们要使用,需要引入 functools 模块来调用 reduce() 函数:
from functools import reduce def add(x, y) : # 两数相加 return x + y sum1 = reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5 sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数 print(sum1) # 15 print(sum2) # 15
filter()
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
语法:
filter(function, iterable)
filter()接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
Python2.7 返回列表,Python3.x 返回迭代器对象
# 过滤列表中奇数
def is_odd(n): return n % 2 == 1 newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(newlist) # [1, 3, 5, 7, 9]
enumerate()
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
Python 2.3. 以上版本可用,2.6 添加 start 参数。
语法:
enumerate(sequence, [start=0])
- sequence -- 一个序列、迭代器或其他支持迭代对象。
- start -- 下标起始位置的值。
>>> seq = ['one', 'two', 'three'] >>> for i, element in enumerate(seq): ... print i, element ... 0 one 1 two 2 three
zip()
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。利用 * 号操作符,可以将元组解压为列表。
zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。
语法:
zip([iterable, ...])
>>> a = [1,2,3] >>> b = [4,5,6] >>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 返回一个对象 >>> zipped <zip object at 0x103abc288>
>>> list(zipped) # list() 转换为列表 [(1, 4), (2, 5), (3, 6)] >>> list(zip(a,c)) # 元素个数与最短的列表一致 [(1, 4), (2, 5), (3, 6)] >>> a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式 >>> list(a1) [1, 2, 3] >>> list(a2) [4, 5, 6] >>>
hasattr() getattr() setattr()
hasattr() 函数用于判断对象是否包含对应的属性。如果对象有该属性返回 True,否则返回 False。
语法:
hasattr(object, name)
class Coordinate: x = 10 y = -5 z = 0 point1 = Coordinate() print(hasattr(point1, 'x'))print(hasattr(point1, 'no')) # 没有该属性
。。。。。。。
True False
getattr() 函数用于返回一个对象属性值。
语法:
getattr(object, name[, default])
>>>class A(object): ... bar = 1 ... >>> a = A() >>> getattr(a, 'bar') # 获取属性 bar 值 1
>>> getattr(a, 'bar2') # 属性 bar2 不存在,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'bar2'
>>> getattr(a, 'bar2', 3) # 属性 bar2 不存在,但设置了默认值 3 >>>
setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的。
语法:
setattr(object, name, value)
>>>class A(object): ... bar = 1 ... >>> a = A() >>> getattr(a, 'bar') # 获取属性 bar 值 1 >>> setattr(a, 'bar', 5) # 设置属性 bar 值 >>> a.bar 5
标签:面试题,bar,函数,zip,列表,注释,import From: https://www.cnblogs.com/erhuoyuan/p/17076614.html