Introduction:
Top Python Interview Questions 2 year experience
1. Explain the Global Interpreter Lock (GIL) in Python and its impact on multi-threading.
The Global Interpreter Lock (GIL) is a mechanism in CPython (the reference implementation of Python) that ensures only one thread executes Python bytecode at a time. In other words, the GIL prevents multiple native threads from executing Python bytecodes simultaneously, even on multi-core systems. This means that although Python supports multi-threading, it does not fully utilize multiple cores for parallel execution.
The purpose of the GIL is to simplify memory management and improve thread safety in Python. It achieves this by serializing access to Python objects, which avoids complications that can arise from concurrent access and modification of shared data structures. As a result, CPython’s memory management becomes simpler, and developers can more easily write thread-safe Python code.
2. How do you handle file I/O operations in Python?
In Python, file I/O operations can be handled using the built-in open() function and various methods available for file objects. Here’s a step-by-step guide on how to handle file I/O operations:
Opening a File: To open a file, you can use the open() function and provide the file path and mode as parameters. The mode can be ‘r’ for reading, ‘w’ for writing (creates a new file or overwrites an existing file), ‘a’ for appending to a file, or ‘x’ for exclusive creation (fails if the file already exists).
Example: file = open("myfile.txt", "r")
Reading from a File: After opening a file for reading, you can use various methods to read its contents:
read(size): Reads and returns size number of characters from the file. If size is not specified, it reads the entire file.
readline(): Reads and returns a single line from the file.
readlines(): Reads and returns a list of lines from the file.
Example : file = open("myfile.txt", "r")
content = file.read() # Read the entire file
print(content)
file.close() # Close the file after reading
Writing to a File: To write to a file, open it in write mode ('w' or 'a') and use the write() method to write content to the file.
Example : file = open("myfile.txt", "w")
file.write("Hello, World!")
file.close()
Appending to a File: If you want to add content to an existing file without overwriting its existing content, open the file in append mode ('a') and use the write() method.
Example: file = open("myfile.txt", "a")
file.write("Appending new content!")
file.close()
Closing a File: It's essential to close the file after you have finished reading or writing to it. This ensures that system resources associated with the file are properly released.
Example : file = open(“myfile.txt”, “r”)
Perform file operations
file.close()
3. Describe the process of handling and raising custom exceptions in Python.
In Python, you can handle and raise custom exceptions to handle specific errors or exceptional conditions that may occur during the execution of your code.
Creating Custom Exceptions: To create a custom exception, you need to define a new class that inherits from the built-in Exception class or one of its subclasses. You can define your own properties and methods within the custom exception class to provide additional information or behavior.
Example: class CustomException(Exception):
pass
Handling Custom Exceptions: To handle custom exceptions, you can use a try-except block. Inside the try block, you write the code that may potentially raise the custom exception. In the except block, you specify the type of exception you want to catch and define the actions to be taken when that specific exception occurs.
Example: try:
Code that may raise a custom exception
Handling the custom exception
print(“Custom exception occurred:”, str(e))
Raising Custom Exceptions: To raise a custom exception, you can use the raise statement followed by an instance of the custom exception class. You can provide any additional information as arguments to the exception class constructor if needed.
Example :
def divide(x, y):
if y == 0:
raise CustomException(“Division by zero not allowed”)
return x / y
try:
result = divide(10, 0)
print(“Result:”, result)
except CustomException as e:
print(“Custom exception occurred:”, str(e))
4. What is the purpose of the init method in Python classes?
The init method, also known as the initializer or constructor, is a special method in Python classes. It is automatically called when a new instance of a class is created. The primary purpose of the init method is to initialize the attributes (variables) of an object and perform any necessary setup or initialization.
Example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print("Person object initialized")
person1 = Person("Alice", 25)
# The __init__ method is called automatically upon object creation
print(person1.name) # Output: Alice
print(person1.age) # Output: 25
5. How does garbage collection work in Python?
Garbage collection in Python is an automatic memory management process that frees up memory occupied by objects that are no longer needed or referenced by any part of the program.
Generational Garbage Collection: To further optimize the garbage collection process, Python uses generational garbage collection. It divides objects into different generations based on their age. Younger objects are more likely to become garbage compared to long-lived objects.Python employs three generations: young (0), middle (1), and old (2). Most objects start in the young generation and are collected frequently. If an object survives a certain number of collections, it gets promoted to the next generation. This approach reduces the time spent on garbage collection by focusing primarily on the younger generations.
Automatic Garbage Collection: Garbage collection in Python is automatic and transparent to developers. The interpreter periodically checks and triggers the garbage collection process when certain conditions are met, such as when the number of allocated objects exceeds a threshold.However, Python also provides a module called gc that allows manual control over the garbage collection process. Developers can disable or enable the garbage collector, perform explicit garbage collection, or modify its behavior using the gc module’s functions and settings.
6. Explain the difference between a generator function and a normal function in Python.
Feature Generator Function Normal Function
Syntax Uses the yield keyword Does not use the yield keyword
Execution Generates values one at a time Returns all values at once
Memory usage More memory efficient Less memory efficient
Use cases Ideal for tasks that do not require all values at once, such as iteration over a large dataset Ideal for tasks that require all values at once, such as calculating the sum of a list of numbers.
Here is an example of a generator function:
def generate_numbers():
for i in range(10):
yield i
Here is an example of a normal function:
def sum_numbers(numbers):
total = 0
for number in numbers:
total += number
return total
7. How can you perform unit testing in Python? Mention any relevant testing frameworks.
Unit testing is a software testing method by which individual units of source code, such as classes, functions, and modules, are tested to determine if they meet their design and functional requirements. Unit testing can be performed manually or using a unit testing framework.
There are many unit testing frameworks available for Python, some of the most popular ones are:
unittest is the standard unit testing framework that comes with Python. It is easy to use and provides a basic set of features for writing unit tests.
pytest is a popular unit testing framework that is known for its flexibility and powerful features. It is easy to learn and use, and can be used to write both unit tests and integration tests.
nose is a unit testing framework that is known for its speed and efficiency. It is easy to use and can be used to write both unit tests and integration tests.
To perform unit testing in Python, you will need to:
Write a unit test for each unit of code that you want to test. A unit test is a small piece of code that checks the behavior of a unit of code.
Arrange the input data for the unit test. The input data should be representative of the data that the unit of code will be used with.
Act on the unit of code with the input data. This can be done by calling the unit of code or by passing the input data to the unit of code.
Assert the expected output of the unit of code. The expected output should be the output that you expect the unit of code to produce with the input data.
Once you have written your unit tests, you can run them using the unit testing framework that you have chosen. The unit testing framework will run each unit test and report the results. If a unit test fails, the unit testing framework will provide you with information about the failure so that you can fix the problem.
Unit testing is an important part of software development. It helps to ensure that your code is correct and works as expected. By performing unit testing, you can catch bugs early in the development process, which can save you time and money.
8. Explain the concept of list comprehension in Python with an example.
List comprehension is a concise and elegant way to create lists in Python. It allows you to generate a new list by applying an expression or operation to each element of an existing iterable (such as a list, tuple, or string), optionally with filtering conditions.
Example 1: Squaring Numbers Let’s say we have a list of numbers and we want to create a new list containing the squares of those numbers
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares) //output [1, 4, 9, 16, 25]
Example 2: Filtering Even Numbers List comprehension also allows you to include conditional statements to filter elements based on certain criteria. Let’s consider an example where we want to create a new list containing only the even numbers from an existing list.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers) //output [2, 4, 6, 8, 10]
9.What are lambda functions in Python? Provide an example of their usage.
In Python, lambda functions, also known as anonymous functions, are small, single-line functions that don’t require a separate def statement like regular functions. Lambda functions are typically used for simple, one-time operations where defining a named function is unnecessary or impractical.
They are created using the lambda keyword and can take any number of arguments but can only have one expression.
Here’s an example that demonstrates the usage of lambda functions:
Example 1: Adding Two Numbers
addition = lambda x, y: x + y
result = addition(3, 4)
print(result) //output : 7
Example 2: Squaring Numbers using map()
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x**2, numbers))
print(squared_numbers) //output: [1, 4, 9, 16, 25]
10.Describe the concept of recursion and provide an example of a recursive function in Python.
Recursion is a programming concept in which a function calls itself to solve a smaller instance of the same problem. It involves breaking down a larger problem into smaller subproblems and solving them recursively until a base case is reached.
Recursion is a powerful technique that can simplify the implementation of complex algorithms and problems that exhibit a recursive structure.
Here’s an example of a recursive function in Python: