This lesson answers five practical Python interview questions with simple, beginner-friendly explanations, real-world analogies, and runnable code examples that include expected output. Read slowly, try each example in your editor, and use the short lists to anchor the main ideas.
Duck typing is a style of dynamic typing where the suitability of an object is determined by the presence of methods and attributes, not by its explicit type. The classic phrase is: "If it walks like a duck and quacks like a duck, it's a duck." In practice, this means you write code that operates on objects that implement the expected behavior, rather than checking the object's class.
Example: a function that expects something that can be iterated and printed. It doesn't care about the concrete type.
def print_all_things(things):
"""
We only assume 'things' is iterable and its items are printable.
"""
for item in things:
print(item)
# Works for a list
print_all_things([1, 2, 3])
# Works for a generator
print_all_things(x * x for x in range(3))
# Works for a custom container that implements __iter__
class Bag:
def __init__(self, items):
self._items = list(items)
def __iter__(self):
return iter(self._items)
print_all_things(Bag(["apple", "banana"]))
Expected output when run:
# Output:
1
2
3
0
1
4
apple
banana `==` checks for value equality - it asks "are these two objects equal in value?" `is` checks for identity - it asks "are these two names pointing to the exact same object in memory?" In everyday terms: `==` compares the contents written on two index cards; `is` checks whether both index cards are the very same physical card.
Examples showing both behaviors:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True, same contents
print(a is b) # False, different objects
print(a is c) # True, same object
x = None
print(x is None) # True - use 'is' for None checks Expected output:
# Output:
True
False
True
True Python uses an object model with automatic memory management. Every value in Python is an object; variables are simply names (references) that point to objects. Memory allocation and reclaiming are handled by the Python runtime (the interpreter), primarily via reference counting plus a cyclic garbage collector to clean cycles.
Simple demonstration showing identities and shared references:
a = [1, 2, 3]
b = a # b references the same list object
c = a.copy() # c is a new list with the same contents
print(id(a)) # object id of a
print(id(b)) # same as a
print(id(c)) # different id
# Changing through one name affects the shared object:
b.append(4)
print(a) # [1, 2, 3, 4] Expected output (ids will differ on your machine; shown here as placeholders):
# Output (example):
140319123456320
140319123456320
140319123457088 [1, 2, 3, 4] Notes and interview tips:
The `with` statement simplifies resource management by ensuring setup and teardown code runs reliably. It's commonly used for files, locks, and network connections. Objects used in a `with` block implement the context manager protocol - they provide `__enter__` (setup) and `__exit__` (cleanup) methods.
File-handling example and a simple custom context manager:
# Using with for file handling
with open("example.txt", "w") as f:
f.write("hello")
# File is closed automatically here
# Custom context manager
class Timer:
import time
def enter(self):
self.start = self.time.time()
return self
def exit(self, exc_type, exc, tb):
self.end = self.time.time()
print(f"Elapsed: {self.end - self.start:.4f}s")
with Timer():
total = sum(range(1000000)) # do some work Example output (timing will vary):
# Output (example):
Elapsed: 0.0357s Python's import system locates and loads modules so you can reuse code. When you write `import module`, Python follows a defined process: it searches for the module in a set of locations (the module search path), loads and executes the module file once, and caches the loaded module in `sys.modules` so subsequent imports are fast and consistent.
Small example demonstrating import behavior and `sys.modules` caching:
# Create a module file named mymod.py with:
# print("mymod loaded")
# value = 42
# Then run this script:
import importlib, sys
import mymod # prints "mymod loaded"
import mymod # no print, loaded from sys.modules
importlib.reload(mymod) # forces re-execution and prints again
print("mymod.value =", mymod.value) Expected terminal sequence:
# Output:
mymod loaded
mymod loaded
mymod.value = 42 Interview tips for imports:
Closing notes: These five topics often come up in interviews because they reveal both conceptual understanding and practical habits. Practice writing small programs that demonstrate each idea, and when answering in interviews, use short analogies (like "names point to objects" or "duck typing: if it quacks...") to make your explanation friendly and memorable.
3 questions · no sign-up, nothing stored
Progress is stored in this browser only - no sign-up, nothing sent anywhere.