Explain the difference between a list and a tuple in Python.
Answer:
Lists are mutable, meaning their elements can be changed after creation, and are defined using square brackets []. Tuples are immutable, meaning their elements cannot be changed, and are defined using parentheses (). Tuples are generally faster and can be used as dictionary keys.
What is a dictionary comprehension? Provide an example.
Answer:
A dictionary comprehension is a concise way to create dictionaries. It consists of an expression followed by a for clause, then zero or more for or if clauses. For example: squares = {x: x*x for x in range(5)} creates {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}.
What is the purpose of *args and **kwargs in function definitions?
Answer:
*args allows a function to accept an arbitrary number of positional arguments, which are collected into a tuple. **kwargs allows a function to accept an arbitrary number of keyword arguments, which are collected into a dictionary. They enable flexible function signatures.
Explain the concept of a decorator in Python.
Answer:
A decorator is a design pattern that allows you to modify or extend the functionality of a function or method without explicitly changing its source code. It's essentially a function that takes another function as an argument, adds some functionality, and returns a new function. They are commonly used for logging, timing, or access control.
What is the difference between __init__ and __new__ methods in Python classes?
Answer:
__new__ is a static method responsible for creating and returning a new instance of the class before __init__ is called. __init__ is an instance method that initializes the newly created object. __new__ is rarely overridden unless you need to control object creation itself, like for singletons.
Describe method overriding and method overloading in Python.
Answer:
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. Python does not support traditional method overloading (multiple methods with the same name but different parameters) directly; instead, you can use default arguments or *args/**kwargs to achieve similar flexibility.
What is a generator in Python and why would you use it?
Answer:
A generator is a function that returns an iterator that produces a sequence of results one at a time using the yield keyword, instead of returning a single value. They are memory-efficient because they don't store the entire sequence in memory, making them ideal for large datasets or infinite sequences.
Explain the Global Interpreter Lock (GIL) in Python.
Answer:
The GIL is a mutex that protects access to Python objects, preventing multiple native threads from executing Python bytecodes at once. This means that even on multi-core processors, only one thread can execute Python bytecode at any given time. It simplifies memory management but can limit true parallel execution for CPU-bound tasks.
What is the purpose of super() in Python?
Answer:
super() is used to call a method from a parent or sibling class. It allows you to access inherited methods that have been overridden in a subclass, ensuring proper method resolution order (MRO) in complex inheritance hierarchies. It's commonly used in __init__ methods of subclasses.
How do you handle exceptions in Python? Provide a basic example.
Answer:
Exceptions are handled using try, except, else, and finally blocks. The try block contains code that might raise an exception. except catches specific exceptions. else runs if no exception occurs, and finally always runs, regardless of whether an exception occurred. Example: try: 1/0 except ZeroDivisionError: print('Cannot divide by zero').
What is the difference between shallow and deep copy?
Answer:
A shallow copy creates a new compound object but then inserts references to the objects found in the original. If the original contains mutable objects, changes to those objects will be reflected in the shallow copy. A deep copy creates a new compound object and then recursively inserts copies of the objects found in the original, ensuring complete independence.
Explain the concept of context managers and the with statement.
Answer:
Context managers provide a clean way to manage resources, ensuring that setup and teardown operations are handled correctly, even if errors occur. The with statement is used to automatically handle the acquisition and release of resources. Common uses include file handling, database connections, and locks, ensuring resources are properly closed.