10 个高级 Python 面试问题

随着 Python 最近变得越来越流行,你们中的许多人可能正在接受与 Python 打交道的技术面试。在这篇文章中,我将列出十个高级 Python 面试问题和答案。

这些内容可能会令人困惑,并且针对的是中级开发人员,他们需要对 Python 作为一种语言及其背后的工作原理有很好的理解。

1、Nolocal 和 Global 关键字的用途是什么?

这两个关键字用于更改先前声明的变量的范围。nolocal当您需要访问嵌套函数中的变量时经常使用nolocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。

def func1():
    x = 5
    def func2():
        nolocal x
        print(x)
    func2()

global是一个更直接的指令。它使先前声明的变量成为全局变量。例如,考虑这段代码:

x = 5
def func1():
    print(x)
func1()
>>>5

由于x在函数调用之前声明,因此func1可以访问它。但是,如果您尝试更改它:

x = 5
def func2():
    x += 3
func2()
>>>UnboundLocalError: 赋值前引用了局部变量“c”

为了让它工作,我们需要指出x我们指的是全局变量x

x = 5
def func2():
    global x
    x += 3
func2()

2、class方法和静态方法有什么区别?

它们都定义了一个class方法,可以在不实例化class的对象的情况下调用该方法。唯一的区别在于他们的签名:

A class:
    @staticmethod
    def func1():
        pass
    @classmethod
    def func2(cls):
        pass

如您所见,classmethod接受一个隐式参数cls,该参数将被设置为classA本身。一个常见的用例classmethod是创建替代的可继承构造函数。

3、什么是 GIL 以及绕过它的一些方法是什么?

GIL 代表全局解释器锁,它是 Python 用于并发的一种机制。它内置于 Python 系统的深处,目前无法摆脱它。GIL 的主要缺点是它使线程不是真正的并发。它锁定了解释器,即使看起来你正在使用线程,但它们并不是同时执行的,从而导致性能损失。这里有一些绕过它的方法:

  • multiprocessing模块。它允许您生成新的 Python 进程并以与管理线程相同的方式管理它们。
  • asyncio模块。它有效地启用了异步编程并添加了async/await语法。虽然它没有解决 GIL 问题,但它会使代码方式更易读和更清晰。
  • Stackless_Python这是一个没有 GIL 的 Python 分支。它最显着的用途是作为 EVE Online 游戏的后端。

3、什么是metaclass以及何时使用它们?

metaclass是class的class。当继承过于混乱时,元class可以指定许多class共有的某些行为。一种常见的元class是ABCMeta,用于创建抽象class。

Python 中的元class和元编程是一个很大的话题。如果您对此感兴趣,请务必阅读更多相关信息。

4、什么是class型注解?什么是通用class型注释?

虽然 Python 是一种动态class型语言,但为了清晰起见,有一种方法可以对class型进行注释。这些是内置class型:

  • int
  • float
  • bool
  • str
  • bytes

typing模块提供了复杂class型:

  • List
  • Set
  • Dict
  • Tuple
  • Optional
  • ETC。

以下是如何使用class型注释定义函数:

def func1(x: int, y: str) -> bool:
    return False

泛型class型注解是将另一种class型作为参数的注解,允许你指定复杂的逻辑:

  • List[int]
  • Optional[List[int]]
  • Tuple[bool]

请注意,这些仅用于警告和静态class型检查。您将无法在运行时保证这些class型。

5、什么是生成器函数?编写您自己的范围版本

生成器函数是可以在return值后暂停执行的函数,以便稍后恢复执行并return另一个值。这是pass关键字实现的yield,您使用它代替 return。您使用过的最常见的生成器函数是range. 这是实现它的一种方法(仅适用于积极的步骤,我将把它留作练习以制作支持消极步骤的方法):

def range(start, end, step):
    cur = start
    while cur > end:
        yield cur
        cur += step

6、什么是 Python 中的装饰器?

Python 中的装饰器用于修改函数的行为。例如,如果您想记录对一组特定函数的所有调用、缓存其参数和return值、执行基准测试等。

装饰器以符号为前缀@,并放置在函数声明之前:

@my_decorator
def func1():
    pass

7、什么是 Python 中的 Pickling 和 Unpickling?

序列化的 Python 方式. Pickling 允许您将对象序列化为字符串(或您选择的任何其他内容),以便持久存储或pass网络发送。Unpickling 是从字符串中恢复原始对象的过程。Pickling 是不安全的。只从受信任的来源中提取对象。

下面是你将如何 pickle 一个基本的数据结构:

import pickle
cars = {"Subaru": "best car", "Toyota": "no i am the best car"} cars_serialized = pickle.dumps(cars)
# cars_serialized 是一个字节串new_cars = pickle.loads(cars_serialized)

8、什么是*argsPython**kwargs函数?

这些与拆包密切相关。如果你放入*args函数的参数列表,所有未命名的参数都将存储在args数组中。**kwargs工作方式相同,但对于命名参数:

def func1(*args, **kwargs):
    print(args)
    print(kwargs)
func1(1, 'abc', lol='lmao')
> [1, 'abc']
> {"lol": "lmao" }

9、文件有什么.pyc用?

.pyc.class文件包含 Python 字节码,与Java 中的文件相同。不过,Python 仍然被认为是一种解释型语言,因为这个编译阶段发生在您运行程序时,而在 Java 中,它们是明确分开的。

10、你如何在 Python 中定义抽象class?

ABC您从模块继承来定义抽象 abc

from abc import ABC,abstractmethod
class AbstractCar(ABC):
    @abstractmethod
    def drive(self):
        pass

要实现该class,只需继承它:

class 红旗汽车(AbstractCar):

      def drive(self):

          print('go go go')

if __name__ == '__main__':

      a = 红旗汽车()

      a.drive()

猜你喜欢

转载自blog.csdn.net/qq_35918970/article/details/130066132