title: Interview questions in depth: Python language features description: In Python interviews, language features are a must. Understanding these underlying mechanisms will not only help you cope with interviews, but also avoid writing bugs that are difficult to troubleshoot in actual development.

The characteristics of the Python language often distinguish candidates based on "understanding the underlying logic" rather than "rote memorization". This article sorts out the high-frequency test points, categorizes them, removes redundancy, highlights the core, and controls it within 3,000 words.


1. Basic variables and scope

1. Parameter passing mechanism: neither value nor reference, it is "passing object reference"

There is no "passing by value" or "passing by reference" in the traditional sense. Its parameter passing rules can be summarized in one sentence: Objects have types, and variables are just labels; when a function passes parameters, it is the label that is copied. This metaphor comes from "Daoman Notes" and is very vivid:

  • If you pass an immutable object(intstrtuple), reassigning this parameter inside the function is equivalent to tearing the label off the original stone and attaching it to a new stone. What you are struggling with is only the temporary label inside the function, and the original label outside is still firmly attached to the old stone.
  • If you pass a mutable object(listdictset), the object is modified in place inside the function (for exampleappendpop), which is equivalent to directly taking out the contents of the box. Because the label is still attached to the same box, all labels attached to this box will see the change.

This sentence is worth saying during the interview. It can help the interviewer quickly judge whether you really understand Python's object model.

def modify(x, y):
    x = 2          # 临时标签 x 指向新对象
    y.append(1)    # 操作原可变对象

a = 1
b = []
modify(a, b)
print(a, b)  # 输出: 1 [1]

2. is vs ==: identity vs value

  • ==call__eq__Compares the values ​​of two objects for equality.
  • isCheck bothid(), determine whether it is the same memory address, that is, whether the identity is the same.

Interview Trap: Python caches-5~256of small integers and some short strings, so when comparing small numbersismay "happen" to beTrue, but this is just an implementation detail and production code should avoid dependencies.

3. LEGB scope search rules

When Python looks for a variable, it searches from the inside out in a fixed order. If it cannot find it, it throwsNameError

  1. L (Local): Inside the current function or method.
  2. E (Enclosing): In nested functions, the local scope of the outer function (the cornerstone of closure).
  3. G (Global): The global scope of the current module.
  4. B (Built-in): Built-in name space, such aslenprintrangewait.

2. Core functions and classes

4. Instance methods, class methods and static methods

The essential difference between the three methods is the binding object and the first parameter:

Method typeDecoratorFirst parameterBinding objectMain purpose
Instance methodsNoneselfInstanceAccess or modify instance status (most commonly used)
Class methods@classmethodclsClassFactory pattern, operation class variables
static method@staticmethodNoneNoneIn-class utility functions, independent of instance and class state

In the interview, you must be able to explain clearly why the class factory method is used@classmethod- because it passesclsReferences to the current class will correctly create subclass instances even if the subclass inherits.

5. Class variables vs instance variables: Pitfalls in attribute lookup

This is one of the easiest pitfalls:

  • Class variables: Defined in the class body, all instances share the same data, often used for counters and default configurations.
  • Instance Variables: usually in__init__passself.xxxDefinition, unique to each instance.

Iron rule to avoid: Unless you clearly want to share data between all instances, always__init__Initialize instance variables here.

# 场景1:不可变覆盖
class Person:
    name = "default"

p1 = Person()
p1.name = "Jack"          # 在实例上新增属性,并未改动类变量
print(Person.name, p1.name)  # default Jack

# 场景2:可变污染
class Container:
    items = []

c1, c2 = Container(), Container()
c1.items.append(1)        # 直接操作类的列表,所有实例共享
print(c2.items)           # [1]

6. __new__ vs __init__: Birth vs Decoration

Image memory: ** comes first__new__Only the rough houses built can have__init__The decoration team**.

  • __new__: Class method, responsible for creating instances and returning them.
  • __init__: Instance method, receive__new__The returned instance is initialized and no other objects can be returned.

Rewriting is rarely needed in daily development__new__, but it is a must-have when subclassing singleton patterns and immutable types.

7. In Python 3super(): Maintain MRO chain

Python 3super()No need to pass the current class and instance, simple and easy to use:

super().__init__()

Its core task is to call the method of the next parent class along MRO (Method Resolution Order) to ensure that each class is only initialized once in multiple inheritance (diamond inheritance). During the actual interview, you can say "C3 algorithm" and "availableClassName.mro()Check the order" will give you a lot of points.


3. Memory management and performance optimization

8. Deep/shallow copy vs assignment

When dealing with nested objects, the memory management differences are immediately magnified:

  • Assignmentb = a: Just add one more label, change one and the other will change.
  • Shallow copycopy.copy(a) / a[:]: Create a new container, but the sub-objects inside are still the original references.
  • Deep copycopy.deepcopy(a): Recursively copy all nested objects. The two objects are completely independent and do not affect each other.

9. Garbage collection (GC) mechanism

Python uses a combination of reference counting as the main method and mark clearing + generational recycling as the supplement:

  1. Reference Count: Each object maintains oneob_refcnt, released immediately after returning to zero. The disadvantage is that it cannot handle circular references.
  2. Mark Clear: Traverse all reachable objects, find "cyclic garbage" that cannot be reached from the root object, and then recycle them.
  3. Generational recycling: Based on the assumption that "most objects live and die", objects are divided into 0/1/2 generations. The young generation is checked more frequently and the old generation is checked less frequently to improve efficiency.

10. Iterators and generators: memory-friendly lazy loading

When a large amount of data needs to be processed, if the data is loaded into the memory in one go (such as a largelist), it is likely to burst the memory. Generators are a powerful tool to solve this problem:

  • Generator is a special iterator that calculates while looping and only remembers the current position every time it is callednext()Only then will the next value be generated.
  • Generator function: useyieldreplacereturn
  • Generator expression:(x for x in range(1000000)), than the list comprehension[]Save more memory.

11. Python 3range()It's the iterator

Python 2range()Directly returns an entire list, Python 3 removes the originalxrange(), currentrange()It is a lazy-loaded iterator with fixed memory. During an interview if you are asked "range(10**9)Will it get stuck?" The answer is no, it only takes up a very small amount of memory.


4. Python 3 exclusive/evolution details

12. String formatting is preferred f-string

Sort by recommendation:

  1. f-string (Python 3.6+): The fastest and most intuitive, supporting any expression and format control within curly braces.
  2. .format(): Powerful, supports positional and keyword parameters.
  3. **%Placeholder **: an old writing method that easily leads to pitfalls in tuple parameters and should be avoided in new code.
name, score = "道满", 98.5
print(f"{name} 的得分是 {score:.2f}")

13. Python 2 vs 3 Key Differences Cheat Sheet

Although Python 2 has withdrawn from the stage of history, you may still be asked about these differences during interviews in old projects:

  • print: From statement toprint()function.
  • Character encoding: Python 3 uses UTF-8 by default, and all strings are Unicode.
  • Integer division:3/2from the past1become what it is now1.5

5. Introduction to high-order features and design patterns

14. Closure: Let the function have "memory"

The definition of a closure is simple: a variable in the outer function is referenced in the nested function, and the outer function returns the inner function.

Even if the outer function has completed execution, the variables referenced by the inline function still survive and are stored in the inline function.__closure__in properties. Closures are the basis for decorators, lazy evaluation, and encapsulating private variables.

15. Decorator: Python’s AOP implementation

The essence of a decorator is a higher-order function that receives a function (or class) and returns an enhanced version of the function (or class). It perfectly embodies the opening and closing principle: open to extension and closed to modification.

Common uses include: logging, permission verification, caching, timing, etc. Interviews often require you to write a simple timing decorator by hand. You need to pay attention to retaining the original function.__name__Equivalent information (availablefunctools.wraps)。

16. Duck Typing: Behavior determines identity

"If it walks like a duck and quacks like a duck, then it is a duck." In Python, you don't need to explicitly inherit an interface, as long as you implement itread()method, it can be used as a file. It makes the code more flexible and less coupled, and is the core embodiment of Python polymorphism.

17. Underscore naming convention (not mandatory, but important)

  • _foo: considered private,from module import *Will not be imported.
  • __foo: Trigger name rewriting to become_ClassName__foo, to prevent unintentional overwriting by subclasses.
  • __foo__: Magic method, defined internally by Python, developers should not customize such names.

18. Metaclass: higher abstraction than class

A common interview question is "What is a metaclass": If a class is a template for creating instances, then a metaclass is a template for creating classes. The default metaclass istype. Metaclasses are rarely used in daily business code, but they are very common in Django ORM, various frameworks and status checkers, and can intercept and modify the definition phase of the class.


6. Quick check of high-frequency scattered test points

19. *argsand**kwargs:Flexible parameters

  • *args: Receive any number of positional parameters, packed into tuples.
  • **kwargs: Receive any number of keyword parameters and package them into a dictionary.
  • Unpacking can also be reversed when calling:func(*[1,2,3], **{'x':1})

Parameter order when defining functions: Ordinary parameters →*args→Default parameters →**kwargs

20. List/Dictionary Comprehension

In modern Python style, derivation is preferred overmapfilterMore intuitively:

[x*2 for x in range(5) if x > 2]
{v: k for k, v in {'a':1, 'b':2}.items()}

21. Why doesn’t Python need function overloading?

Python is a dynamic language. The parameter type and number do not need to be declared, and there is no need to overload:

  • Flexible type: the same function can receiveintstrlistetc any type.
  • Flexible quantity: use default parameters,*argsand**kwargsIt can handle a variety of calling methods.

The full text covers the core knowledge points of the language features in the Python interview. Later, you can also delve into intermediate and advanced topics such as GIL, coroutines, and singleton patterns separately.