python常见问题
1.列表、元组的相加是怎样实现的?
(1)列表相加:①利用操作符+,例:
a=[1,2,3],b=[4,5,6],c=a+b=[1,2,3,4,5,6]
②利用extend ,例:
a=[1,2,3],b=[4,5,6],a.extend(b)--->结果是[1,2,3,4,5,6]
操作符+生成了一个新对象,而extend是修改原对象。
(2)元组相加:直接采用操作符 +
2.内嵌函数和闭包有什么区别?
内嵌函数(函数嵌套):又称内置函数,即在函数中定义函数,内嵌函数的作用域在外部函数之内;
闭包:闭包是函数式编程的重要语法结构,提高了代码的可重复使用性。当一个内嵌函数引用其外部作用域的变量就会得到一个闭包。
创建闭包必须满足以下几点:①必须有一个内嵌函数;②内嵌函数必须引用外部函数中的变量;③外部函数的返回值必须是内嵌函数。
#函数嵌套:在函数内部再定义函数 def
#函数嵌套中优先寻找本层定义变量,再一层层往外找;最外层变量可以渗透到做内层
def father(name):
print('from father %s' %name)
def son():
name = 'danny_1'
print('我的爸爸是%s' %name)
def grandson():
name = '就是自己'
print('我的爷爷是%s' %name)
grandson() #打印当前层的局部变量
print (locals())
son()
father('Danielle')
3.__new__
和 __init__
的区别?
①__new__是一个静态方法,而__init__是一个实例方法;
②__new__方法会返回一个创建的实例,__init__什么都不返回;
③只有在__new__返回一个cls的实例时后边的__init__才能被调用;
④当创建一个新实例时调用__new__,初始化一个实例时用__init__。
4.用python 怎样实现文件的读写功能(怎样实现python中的with功能)?
文件读写的操作步骤如下:①打开文件,获取文件描述符;②操作文件描述符的读写;③关闭文件。
with语句不仅仅用于文件操作,实际上是一个很通用的结构,允许使用上下文管理器。上下文管理器支持__enter__()
和__exit__()
这两个方法,__enter__()
方法不带任何参数,在进入with语句块的时候被调用,该方法的返回值会被赋值给as关键字之后的变量。__exit__()
方法带有3个参数:type(异常类型)、value(异常信息)、trace(异常栈),当with语句的代码块执行完毕或执行过程中因为异常而被终止都会调用__exit__()
方法。正常退出时该方法的3个参数都为None,异常退出时该方法的3个参数会被分别赋值。如果__exit__()
方法返回值(真值测试结果)为True则表示异常已经被处理,命令执行结果中就不会抛出异常信息了;反之,如果__exit__()
方法返回值(真值测试结果)为False,则表示异常没有被处理并且会向外抛出该异常。
with在操作文件时可以自动关闭文件,简化操作。其功能可用try…except…finally…异常处理机制来代替,无论有无异常,最终都将文件关闭掉。
5.python生成器在实际程序中怎样展现出来的?
生成器:可以理解为一种数据类型,这种数据类型自动实现了迭代器协议,生成器就是可迭代对象。
生成器函数:常规函数定义,但是用yield
语句而不是用return语句返回结果,yield一次返回一个结果,自动实现迭代器协议(自动实现__next__()
方法,无需再去调用__iter__()
方法),调用生成器函数,不会立马执行该函数里边的代码,而是回返回一个生成器。
生成器可以将列表推导式的[]改成(),不会将所有的值一次性加载到内存当中,延迟计算,一次返回一个结果,不会一次生成所有结果;省内存,提高代码的可读性,生成器的好处是延迟计算,一次返回一个结果,生成器只能遍历一次。
6.什么是列表推导式?具体有何优点?
列表推导式是python中一种常用的数据结构。列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据判断条件创建子序列。每个列表推导式都在for之后跟一个表达式,然后有0或多个for或if子句,返回结果是一个根据表达从其后的for和if上下文环境中生成出来的列表,如果希望表达式推导出一个元组,就必须使用括号。
列表推导式将所有的值一次性加载到内存中,可以遍历任意次;利用其它列表可以创建新列表。
#也可以理解为三元表达式
list=[2,4,6]
list1=[4,3,-9]
freshfruit=[' banana',' loganberry ','passion fruit ']
>>>[3*x for x in list]--->[6,12,18]
>>>[[x,x**2] for x in list]--->[[2,4],[4,16],[6,36]]
>>>[2*x for x in list if x>4]--->[8,12]
>>>[2*x for x in list if x<2]--->[]
>>>[a.strip() for a in freshfruit]
--->['banana','loganberry','passion fruit']
>>>[x*y for x in list for y in list1]
--->[8,6,-18,16,12,-36,24,18,-54]
>>>[list[i]*list1[1] for i in range(len(list))]
--->[6,12,18]
>>>[str(round(355/113,i)) for i in range(1,6)]
--->['3.1','3.14','3.142','3,1416','3.14159']
7.列表的sort()排序方法和python内置sorted排序方法有什么区别?
sort()函数是list列表中内置的函数,而sorted()可以对list或者iterator进行排序;用sort函数对列表排序会影响列表本身,而sorted()不会,python内置的全局sorted()方法对可迭代的序列排序生成新的序列;sorted()对所有的可迭代序列都有效。
8.列表、字典、元组如何实现比较大小的?
列表比较:==、>、< 或者使用 is,返回布尔值true或False。列表比较是从第一个元素顺序开始比较,如果相等则继续,直到找到第一个不相等的元素并返回比较结果,如果一个列表的所有元素与另一个列表对应位置的元素都相等,则长的列表大。
字典的比较都是通过返回的整数值来比较大小的,字典的比较提供了一个cmp()方法:①比较字典的长度,如果字典的长度不同,用cmp(dict1,dict2)比较大小时,若果dict1比dict2长,cmp()返回正值,反之返回负值,字典中键的个数越多,这个字典就越大;②比较字典的键,如果两个字典的长度相等,就比较字典的键,键的比较顺序和keys()方法返回键的顺序相同(相同的键会映射到哈希表的同一位置,保证字典键的检查的一致性),若果两个字典的键不匹配,对这两个键比较大小就可以了,如果dict1中的第一个不同的键大于dict2中第一个不同的键,cmp()返回正值;③如果两个字典的长度相同并且他们的键也相同,则用每个相同的键所对应的值进行比较,一旦出现不匹配的值,就可以对字典进行比较了,如果dict1比dict2中相同的键的值大,cmp()返回正值,dict1>dict2;④如果两个字典有相同的长度,相同的键,相同的值,则两个字典相同,cmp()返回0。
9.python中常用的工具包有哪些?
1.字符串处理:
①re:正则表达式的标准库;
②StringIO/cStringIO:以读写文件的方式操作字符串;
③chardet:可以猜测任意一段文本的字符集编码,对于编码类型未知的文本,很有用。可以作为模块来使用,也可以作为命令行工具来使用。
2.数学类:
①math:数学标准库,封装了常用的数学函数;
②random:用于生成随机数;
③fractions:封装跟有理数(分数)相关的运算。
3.安全类:
①hashlib:计算各种散列值,支持的哈希算法有(MD5,SHA1,SHA224,SHA256,SHA384,SHA512);
②PyCrypto:包含常用的对称加密算法(DES,AES,IDEA);
③pyOpenSSL:这个库使用python对OpenSSL进行很薄的封装;
4.数据结构类:
collections模块中的namedtuple、defaultdict、deque、counter、ordereddict、ChainMap;
5.web重要类:requests 中的urllib、urllib2、urllib3(基于HTTP的重要模块)。
#time模块
time.time() 时间戳1970至今的时间秒数,用于做计算;
t=time.localtime() print(t.tm_year) 打印具体的年月日等;
time.gmtime() 结构化时间 ;
time.mktime() 将结构化时间转换为时间戳;
time.strftime(“%Y-%m-%d %X”,time.localtime())--将结构化时间转换为字符串时间;
time.strftime(“2018:07:30:17:50:36”,”%Y:%m:%d:%X”)将字符串时间转换为结构化时间;
time.asctime()/time.ctime() -设定好格式的时间表示(星期 月份 日期 时间 年);
datetime.datetime.now() 显示年月日时分秒的样子;
#random模块
random.random() 打印0-1的浮点数;
random.randint(1,3) 1,2,3
random.rangrange(1,3) 1,2
random.choice([11,22,33])随机取出一个元素;
random.sample([11,22,33],2)随机取出2个元素;
random.uniform(1,3) 生成1-3中任意的浮点数;
ramdom.shuffle(item) 打乱(洗牌);
#os模块
os.getcwd()获取当前工作目录;
os.chdir()改变当前工作目录;
os.makedirs(‘name1/name2’建立多层目录);
os.removedirs(“name1/name2”)删除文件(只删除空文件);
os.listdir(“name1”)显示指定文件下的文件或目录;
os.stat(“文件”)文件相关信息介绍;
os.system(“dir”)显示当前文件信息;
os.path.join(a,b)默认找出操作系统的拼接符,对a,b路径进行拼接;
os.path.getmtime(path)获取path路径文件修改时间;
#sys模块
sys.path 返回模块的搜索路径,初始化时使用pythonpath环境变量的值;
sys.argv 命令行参数list,可以获取命令行输入的内容;
sys.stdout.write(‘#’)往屏幕上显示 #####;
sys.stdout.flush()刷新屏幕;
#re模块:正则表达式
正则:元字符 . ^ $ * + ? {}
.:通配符,所有字符都可以匹配上,除了 \n;
^:以什么开头的意思,必须在字符串的开头匹配成功,只能在开头匹配;
$:必须在字符串的末尾匹配,以匹配字符结尾;
*:d*匹配紧挨字符的重复,0-无穷,紧挨着的字符可以出现0次;贪婪匹配
+:匹配1-无穷次,即它挨着的字符至少出现一次;贪婪匹配
?:匹配0次或1次;惰性匹配
{ }:万能,,,{0,} == *
{1,}== +
{0,1} == ?
{6} 重复6次
{1,6} 重复1到6中任意次数
[]:字符集;”x[yz]p” [‘xyp’,’xzp’],字符集[]中没有特殊符号,除外的 -(a-z表示范围);
X[^a-z]非a-z的范围;
\:转义字符(元字符变成普通字符,普通字符变得有意义);
\d:匹配任何十进制数,相当于[0-9]
\D:匹配任意非数字字符,相当于[^0-9]
\s:匹配任何空白字符,相当于[\+\n\r\f\n]
\S:匹配任何非空白字符,相当于[^ \+\n\r\f\n]
\w:匹配任何字母数字字符,相当于[a-zA-Z0-9_]
\W:匹配任何非字母数字字符,相当于[^ a-zA-Z0-9_]
\b:匹配一个特殊字符边界,比如空格 & #等;
\特殊符号:将特殊符号转换成一般符号。
|:或的意思。匹配 | 前面的或者后面的;
():分组,(abc)匹配abc为组的信息;
re.findall(‘匹配规则’,‘被匹配字符串’),把字符串里面所有的能匹配到的结果,用列表展示出来(放到列表里);
re.search():匹配字符串中的结果,只要能找到一个就不再匹配;匹配成功返回一个对象,失败返回空;
re.search().group()-打印出匹配结果;
re.match():匹配成功返回一个对象,失败也是空;只从开始匹配;
re.split():根据特定字符 分割 ,返回列表;此处容易分出空的,是个坑。
re.sub(匹配规则,替换内容,被替换内容,匹配次数),做替换,结果是字符串;
re.subn(匹配规则,替换内容,被替换内容,匹配次数),做替换,结果放在一个元组里,并显示匹配次数;
com = re.compile(‘\d+’) com.findall(字符串)不用写匹配规则;编译匹配规则;
re.finditer():将所有结果封装到一个迭代器,返回一个迭代器,不会将所有数据放到内存中,next()用一条取一条,取出来的也是一个对象;
#logging模块
logging.basicConfig(level = logging.DEBUG, 设定日志级别
filename = “log.log”, 日志存储位置
filemode = “w”, 日志文件添加格式
format = “%(asctime)s [%(lineno)d] %(message)s %(filename)s” 显示格式(时间 行号 信息 文件名称)
)
logging.debug(“debug”)
logging.info(“info”)
logging.warning(“waring”)
logging.error(“error”)
logging.critical(“critical”)
#logger:
#设置logger格式-----------------------------------------
logger = logging.getLogger() :括号不加参数相当于根,加参数的话,相当于子用户,logger是一棵树,创建对象,子对象打印时会将父节点也执行一遍(当父节点在工作时)
fh = logging.FileHandler()
ch = logging.StreamHandler()
fm = logger.Formatter(“%(asctime)s [%(lineno)d]”)
fh.setFomatter(fm) 将内容格式放进来
ch.setFormatter(fm) 将内容格式放进来
logger.addHandler(fh) 往文件发送内容
logger.addHandler(ch) 往屏幕发送内容
logger.setLeval(“DEBUG”) 设定logger 日志级别
#调用logger----------------------------------------------
logger.debug(“hello”)
logger.info(“hello”)
logger.warning(“hello”)
logger.error(“hello”)
logger.critical(“helllo”)
#hashlib模块 提供摘要算法
#MD5, SHA1, SHA224, SHA256, SHA384, SHA512
obj = hashlib.md5()
obj.update(“root”,encode(“utf8”)) 将root转化成密文
print(obj.hexdigest()) 打印密文内容
configparser 模块 配置文件
#config文件增删改查(类似字典操作)
config.read(‘example.ini’)
print(config.sections())打印config内容
print(config.options()) 拿出键
print(config.items()) 拿出键值对
print(config.get()) 取出键下面对应键的值
10.python中常用的数据结构有哪些?
(1)数字
(2)字符串
(3)列表[list]
(4)元组(tuple)
(5)字典{dict}
(6)集合({set})
11.字典中哪些数据类型可以成为key值(或是满足了怎样的条件就可以成为字典的key值)?
凡是可哈希的数据结构都可以作为字典的键值。可哈希:一个对象在自己的生命周期中是不可变的(不可变的数据结构),则称该对象是可哈希的。字典的键值基本原则是唯一且不可变,其存储结构是一张哈希表,所以可哈希的对象都可以作为字典的键值。
数值、字符串、元组、frozenset(不可变集合)等都可以作为字典的键值;列表、字典、集合等不可以作为字典的键值。
上一篇: ionic在mac上的环境搭建与模拟测试
下一篇: js监听回车登录