10个Python面试高频考点与核心机制解析

码头散步
码头散步
发布时间:2026-10-11 | 3人浏览过
原创

本文总结了Python面试中关于类机制、推导式、变量作用域及闭包等高频考点。通过具体代码示例,深入解析__new__与__init__的执行顺序、__getattr__的动态方法调用、列表与字典推导式的用法,以及全局变量修改与闭包函数的实现原理,帮助开发者系统掌握Python核心特性。

类机制与对象创建

在Python面试中,理解对象的创建过程至关重要。这涉及两个核心魔术方法:__new__和__init__。

1. __new__与__init__的执行顺序

__new__负责决定返回哪个对象实例,它在对象创建之前被调用;而__init__则在对象创建完成后调用,用于初始化属性。利用这一特性,可以实现单例模式或工厂模式。

class B(object):
  def fn(self):
    print 'B fn'
  def __init__(self):
    print "B INIT"

class A(object):
  def fn(self):
    print 'A fn'

  def __new__(cls,a):
      print "NEW", a
      if a>10:
        return super(A, cls).__new__(cls)
      return B()

  def __init__(self,a):
    print "INIT", a

a1 = A(5)
a1.fn()
a2=A(20)
a2.fn()

上述代码中,当传入参数a=5时,A.__new__返回B的实例,因此调用a1.fn()输出'B fn';当a=20时,返回A的实例,输出'A fn'。

2. 动态修改类与方法调用

可以通过修改实例的__class__属性来动态改变其行为。例如,将B类实例obj的类指向A,即可调用A的方法。但需注意,修改后应记得将__class__恢复原状,以免影响后续逻辑。

class A(object):
  def show(self):
    print 'base show'

class B(A):
  def show(self):
    print 'derived show'
 
obj = B()
obj.show()
obj.__class__ = A
obj.show() 

3. 实现对象的可调用性

若希望对象实例能像函数一样被直接调用,需实现__call__方法。结合私有属性(如self.__a),可以构建具有状态的计算对象。

class A(object):
  def __init__(self, a, b):
    self.__a = a
    self.__b = b
  def myprint(self):
    print 'a=', self.__a, 'b=', self.__b
  def __call__(self, num):
    print 'call:', num + self.__a

4. __getattr__与动态方法处理

当调用未定义的方法时,Python会触发__getattr__。该方法仅在找不到属性时执行。为了兼容带有参数的方法调用,可以为__getattr__返回的函数增加*args参数。

class A(object):
  def __init__(self,a,b):
    self.a1 = a
    self.b1 = b
    print 'init'
  def mydefault(self,*args):
    print 'default:' + str(args[0])
  def __getattr__(self,name):
    print "other fn:",name
    return self.mydefault
 
a1 = A(10,20)
a1.fn1(33)
a1.fn2('hello')
a1.fn3(10)

推导式与集合运算

推导式是Python中简洁高效的数据处理工具,常用于列表、字典和集合的生成。

1. 列表推导式

列表推导式支持条件过滤和表达式变换。例如,从列表[1,2,3,4]中筛选大于2的元素,或生成加倍后的列表:

ls = [1,2,3,4]
list1 = [i for i in ls if i>2]
print list1  # 输出: [3, 4]

list2 = [i*2 for i in ls if i>2]
print list2  # 输出: [6, 8]

2. 字典与集合推导式

字典推导式可生成键值对映射,集合推导式则用于去重或特定字符筛选:

dic1 = {x: x**2 for x in (2, 4, 6)}
print dic1  # 输出: {2: 4, 4: 16, 6: 36}

dic2 = {x: 'item' + str(x**2) for x in (2, 4, 6)}
print dic2  # 输出: {2: 'item4', 4: 'item16', 6: 'item36'}

set1 = {x for x in 'hello world' if x not in 'low level'}
print set1  # 输出: set(['h', 'r', 'd'])

变量作用域与闭包

1. 全局变量的修改

在函数内部,默认情况下变量是局部的。若需修改全局变量num,必须使用global关键字声明。否则,函数内的num仅为局部拷贝,不影响全局值。

num = 9

def f1():
  global num
  num = 20

def f2():
  print num

f2()  # 输出: 9
f1()
f2()  # 输出: 20

2. 变量交换技巧

Python支持一行代码交换两个变量的值,无需临时变量:

a=8
b=9
(a,b) = (b,a)

3. 闭包函数的实现

闭包允许内部函数引用外部函数的变量。以下示例展示了如何创建一个乘法生成器:

def mulby(num):
  def gn(val):
    return num * val
  return gn
 
zw = mulby(7)
print(zw(9))  # 输出: 63

模块导入控制

在__init__.py中指定__all__列表,可以控制from demopack import *语句导入的模块范围,避免意外导入内部实现细节。

__all__ = ['mod1','mod3']

以上就是Python面试常问问题的详细内容,更多关于Python类机制、推导式与变量作用域的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表