python知识点

如何在内函数改变外函数的变量?

用global关键字

x = 1
def foo():
	global x	# 注意:没有global x = 2这种写法
	x = 2

展开:这题能用nonlocal吗?

不能,会报错
因为nonlocal只能用在嵌套函数中。
以下这种用法可以:

def outer():
	x = 1
	def inner():
		nonlocal x
		x = 2

global和nonlocal的区别?

  • global:标识全局变量。
  • nonlocal:标识的是上一级函数中的局部变量。(简单来说就是只能用在嵌套函数中,切外层函数定义了相关的局部变量,否则会报错)

(面过)pytest有一个插件可以并发执行用例,是什么?一般适用于什么场景?

pytest-xdist,一般用于用例之间不会使用重复的资源的时候

参数说明

-n auto 自动侦测系统里的CPU数目
-n numprocesses 指定运行测试的处理器进程数

pip install pytest-xdist
pytest -n auto test.py
pytest -n 4 test.py

(面过)pytest有一个插件可以自动重跑失败的用例,是什么?一般适用于什么场景?

pytest-rerunfailures,常用于重跑不稳定性引起的失败。
可以在装饰器使用也可以命令行使用。
由于一些不兼容等问题,推荐只用reruns和reruns-delay两个功能:

pytest --reruns 5 --reruns-delay 1

@pytest.mark.flaky(reruns=5, reruns_delay=1)
def test_foo():
	pass

pytest和unittest有什么区别?

unittestpytest

pytest-cov插件是干什么的?用法?

显示测试覆盖率。

pytest --cov=src/ tests/

显示html页面:

pytest --cov=src/  tests --cov-report html

pytest 中的conftest.py什么作用

(面过)*args和**kwargs是什么?用它们传入的参数分别存为什么类型?

用于传递不定数量的参数。
*args可传入非键值对型参数,存为tuple;**kwargs传入键值对类型参数,存为dict。

# 可以以这种方式将列表作为*args传入
def add(x, y):
     return x + y
lst = [1,2]
add(lst[0], lst[1]) # 1
3
add(*lst) # 2
3
# 可以以这种方式将字典作为**kwargs传入
dct = {'x': 1, 'y': 2}
def bar(x, y):
	return x + y
bar(**dct)
3

(面过)什么是迭代器?什么是生成器?

  • 迭代器是一个可以遍历的对象,包含了一组元素,实现了__iter__()和__next__()方法。当执行next()操作时,返回其中一个元素。当所有元素都被返回后,再执行next()报异常—StopIteration
  • 生成器是使用了yield关键字的函数,这个函数也可以称作是一个迭代器。
    生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和__next__方法),不需要再手动实现这两个方法。

“可迭代对象”有哪些?

  • 列表(list)
  • 元组(tuple)
  • 字符串(string)
  • 集合(set)
  • 字典(dictionary)
  • 自定义的迭代器对象

简单来理解,任何你可以循环遍历的对象都是可迭代对象。

展开:如何判断一个对象是否为可迭代对象?

  1. 使用 isinstance()函数 判断对象是否是可迭代对象
>>> from collections import Iterable
>>> isinstance("kele", Iterable)
True
>>> isinstance(18, Iterable)
False
  1. 使用 dir()函数 查看对象内所有的属性与方法,看是否有__iter__方法
# 字典的所有属性与方法
>>> dir({"name":"kele"})
[..., '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', ...]

# 数字的所有属性与方法
# 并没有找到 __iter__
>>> dir(18)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

展开:迭代器、生成器的应用场景有什么?

比如python的range()方法,见下一题详解。

python2和python3的range()的区别

python2返回列表,python3返回迭代器,节约内存。
python2中有一个xrange(),返回的是迭代器,在python3中已经没有了,因为python3中range()即返回迭代器。

用生成器实现斐波那契数列

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

(面过)简述什么是闭包?

def outer(x):
	def inner(y):
		return x + y
	return inner

如上面代码,闭包的特性:

  1. inner引用outer作用域的变量(即x
  2. outer返回值为inner的吟咏(即inner的函数名

这个inner函数称为闭包

展开:为什么可以直接return inner?它不是一个函数吗?

python中一切都是对象,函数也是对象,所以它可以被return。

闭包常用于什么场景?

常用于实现装饰器。它和接口的概念很像。
2023.5.9:和java的切片(AOP)更像

简述什么是装饰器,有什么作用?

在不用修改原函数代码情况下,就可以给原函数(在函数整体之前或之后)添加新功能(不能实现在原函数内部添加新功能),并且在调用的时候和原来调用一模一样,这里需要注意的是,装饰器是基于闭包环境存在的。

装饰器的执行顺序?若一个函数被多个装饰器装饰,他们的执行顺序?

  1. 函数定义时:从里到外
  2. 函数执行时:从外到里

(面过)with打开文件实现了什么?

实现f.close()
with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的清理操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等;

with xxx as xxx 详解:

with所求值的对象必须有一个enter()方法,一个exit()方法。

紧跟with后面的语句被求值后,返回对象的enter()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的exit()方法。
http://t.csdn.cn/WbxZs

sort()和sorted()的区别?它们里面的key参数有什么用?

sort()在原序列上排序,sorted()不修改原序列,返回一个排序好的新序列。sort()的效率比sorted()高一点。
sort()只能排序list:list.sort()
sorted()可以接受任何iterable对象。

key参数后面带一个函数,这个函数在做比较之前会对序列中的每个元素进行调用。

student_tuples = [
	('john', 'A', 15),
	('jane', 'B', 12),
	('dave', 'B', 10)
]
sorted(student_tuples, key=lambda student: student[2])
# sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

“序列”包括哪些类型?

字符串、列表、元组、集合和字典

静态方法和类方法如何定义?有什么区别?

静态方法无需传入任何参数;类方法传入的第一个参数必须是class本身cls;
静态方法与类方法一旦被调用,内存地址即确定。
不会对任何实例类型进行操作。类方法是将类本身作为对象进行操作的方法。

class Apple:
    def fun1(self):
        return 'normal'

    @staticmethod
    def fun2():
        return 'staticmethod'

    @classmethod
    def fun3(cls):
        return 'classmethod'

python3的除法怎么写?

有两种,“/”和“//”。
/的结果是浮点数,“//”的结果是整除

13/4: 3.25
13//4: 3

定义字典时,d = dict()和d = {}有什么区别?

没有特别大的区别和优缺点。
简单来说就是{}耗时更少,python中用函数(指dict())耗费的资源会更多。
dict()底层实现是c。

>>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...

https://stackoverflow.com/questions/664118/whats-the-difference-between-dict-and

zip()函数的作用

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
# 事实上*号也是一个特殊的运算符,叫解包运算符
[(1, 2, 3), (4, 5, 6)]

https://blog.csdn.net/PaulZhn/article/details/104391756

python2和python3的zip区别?

python3返回的是一个tuple的迭代器(为了节省空间),需要用list()将它强制转换成list。
python2返回的是列表。

zip()的详细用法?

https://blog.csdn.net/PaulZhn/article/details/104391756
可以解“最长公共子串“题

哪些对象可以作为字典的键?

简单来说,字典的键可以是任意不可变类型,需要注意的是tuple元组作为键时,其中不能以任何方式包含可变对象。
一个对象能不能作为字典的key,就取决于其有没有__hash__方法。所以所有python自带类型中,目前我已知的除了list、dict、set和内部带有以上三种类型的tuple之外,其余的对象都能当key。而我们自己定义的类,一般情况下都直接间接的和object有关,都带有__hash__方法。

原文链接:https://blog.csdn.net/lnotime/article/details/81192207

@property的作用?

用来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。
相当于java里的@getter注解,获取对象的值

class DataSet(object):
  @property
  def method_with_property(self): ##含有@property
      return 15
  def method_without_property(self): ##不含@property
      return 15

l = DataSet()
print(l.method_with_property) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
print(l.method_without_property())  #没有加@property , 必须使用正常的调用方法的形式,即在后面加()

展开:上面的代码中,如果调用l.mothod_with_property()或l.method_without_property会怎么样?

会报错

@property对应@getter,那么python中的@setter是怎么写的?

class Solution:
	__number = 1

	@property
	def number(self):
		return __number
	
	@number.setter
	def number(self, v):
		self.__number = v

设计拷贝的几种方式的区别?,赋值、切片、浅拷贝、深拷贝

import copy

if __name__ == '__main__':
    a = [1, 2, {"3": 4}]
    b = a				# 引用,除非直接给a重新赋值,否则a变则b变,b变则a变
    c = a.copy()	 	# 浅复制,只会拷贝父对象, 不会拷贝父对象中的子对象,所以若a的子对象变则c 变,但是a中的第一级对象改变c不会变
    d = copy.copy(a)	# 深拷贝,完全拷贝,完全独立于原对象,a变也不变
    e = a[:]
    f = copy.deepcopy(a)

    a[0] = "new"
    a[2]["3"] = 111
    print(a)
    print(b)
    print(c)
    print(d)
    print(e)
    print(f)

result:

['new', 2, {'3': 111}]
['new', 2, {'3': 111}]
[1, 2, {'3': 111}]
[1, 2, {'3': 111}]
[1, 2, {'3': 111}]
[1, 2, {'3': 4}]

is和==的区别?

is 比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象,是否指向同一个内存地址。
== 比较的是两个对象的内容是否相等,默认会调用对象的__eq__()方法。

可变对象和不可变对象有哪些?

不可变对象 :number,string,tuple
可变对象 :list,dictionary ,set

_ foo、foo_、__foo、foo、_等的意义

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值