- Variable Naming
- Function Naming
- Avoiding Magic Numbers
- List Comprehensions vs Loops
- Error Handling
- Code Duplication
- Using Python’s Built-in Functions
- Avoiding Mutable Default Arguments
- Use of with for File Handling
- Use of Itertools for Efficiency
- Best Practices accepted by community
- Python Naming Conventions
- Interview Questions
a = 10
b = 20
c = a + b
num_apples = 10
num_oranges = 20
total_fruits = num_apples + num_oranges
The Good approach uses descriptive variable names that explain the purpose of the variable. It makes the code more readable and easier to maintain.
def a(x, y):
return x + y
def add_numbers(num1, num2):
return num1 + num2
The Good approach has the function name add_numbers clearly indicates its purpose, and num1 and num2 make it clear what the function expects.
price = 10.5 * 1.2
TAX_RATE = 1.2
price = 10.5 * TAX_RATE
The Good approach assigns 1.2 to a constant with a meaningful name, the code becomes self-explanatory. It’s now clear that TAX_RATE represents a tax multiplier.
squared_numbers = []
for num in range(10):
squared_numbers.append(num * num)
squared_numbers = [num * num for num in range(10)]
The Good approach ensures the List comprehensions are concise, more readable, and often faster than using for loops for simple tasks like creating a list.
try:
result = 10 / 0
except Exception as e:
print("Something went wrong:", e)
try:
result = 10 / 0
except ZeroDivisionError as e:
print("Error: Division by zero is not allowed")
The Good approach is better to catch specific exceptions, such as ZeroDivisionError in this case, so that the error is clear and it’s easier to handle appropriately.
def calculate_area_of_rectangle(length, width):
return length * width
def calculate_area_of_square(side):
return side * side
def calculate_area(length, width=None):
if width is None:
width = length # For square
return length * width
The Good approach reduces code duplication by allowing the same function to calculate the area of both a square and a rectangle, based on whether the width is provided.
squares = []
for i in range(10):
squares.append(i * i)
squares = [i ** 2 for i in range(10)]
The Good approach is a simple task that can be done more efficiently with a built-in function.
def append_item(item, list=[]):
list.append(item)
return list
def append_item(item, list=None):
if list is None:
list = []
list.append(item)
return list
The Good approach using the default value is set to None, and if no list is provided, a new list is created. This prevents the default list from being shared across multiple calls.
file = open("file.txt", "r")
content = file.read()
file.close()
with open("file.txt", "r") as file:
content = file.read()
The Good approach uses with ensures that the file is properly closed, even if an error occurs during file reading. This is cleaner and more robust.
def get_unique_items(lst):
unique_items = []
for item in lst:
if item not in unique_items:
unique_items.append(item)
return unique_items
from itertools import tee
def get_unique_items(lst):
return list(set(lst))
The Good approach uses set automatically removes duplicates in a more efficient way. This is faster and simpler.
Task | Standard Tools | 3rd Party Tools |
---|---|---|
API Authentication | Flask-Login , Django Authentication , Authlib |
Flask-JWT-Extended , PyJWT , Auth0 |
API Client | requests |
httpx , pycurl |
API Documentation | Swagger UI with Flask-RESTPlus , Django REST Framework (DRF) Auto Documentation |
Postman collections , FastAPI (with automatic OpenAPI docs) |
Authentication (OAuth) | OAuthLib , requests-oauthlib |
Authlib , Flask-OAuthlib |
Background Jobs | Celery |
Authlib , Flask-OAuthlib |
Caching | functools.lru_cache , memcached |
Flask-Caching , Django-Redis , cachetools |
CLI Application | argparse |
Click , fire , plac |
Data Processing | pandas , numpy |
Dask , Vaex |
Data Serialization | json , pickle |
Marshmallow , Pydantic |
Database Migrations | Alembic (SQLAlchemy) |
Flyway , Django South |
Database ORM | SQLAlchemy , Django ORM |
Peewee , Tortoise ORM |
Environment Configuration | os.environ , configparser |
python-dotenv , dynaconf |
File Storage | Django Storages , Python's shutil |
Boto3 (AWS S3) , pyFilesystem2 |
File Uploads | Django built-in file handling , Flask File upload |
django-storages , Flask-Uploads , python-dotenv |
Form Handling | WTForms |
django-forms , Flask-WTF , FormEncode |
GraphQL | Graphene |
Ariadne , Strawberry GraphQL |
Image Processing | Pillow |
OpenCV , imageio |
Logging | logging module (built-in) |
Loguru , structlog |
Real-time Communication | Django Channels , Flask-SocketIO |
Socket.IO , websockets |
Request Handling | Flask , Django |
FastAPI , Bottle |
Security | ssl , hashlib , hmac , cryptography |
Flask-Security , Django-Defender , PyCryptodome |
Task Queues | Celery |
RQ , Huey , Dramatiq |
Testing | unittest , pytest , nose2 |
tox , pytest-django |
What | How | Good | Bad |
---|---|---|---|
Class Attributes | Lowercase words separated by underscores (snake_case) | user_name , car_model , account_balance |
UserName , CarModel , AccountBalance |
Classes | Capitalized words (PascalCase) | UserProfile , CarModel , DataProcessor |
userprofile , car_model , dataprocessor |
Constants | Uppercase words separated by underscores (UPPER_SNAKE_CASE) | MAX_RETRIES , PI , DEFAULT_TIMEOUT |
MaxRetries , pi , defaultTimeout |
Enum Names | Capitalized words separated by underscores (UPPER_SNAKE_CASE) | DAY_ONE , STATUS_OK , ERROR_CODE |
DayOne , StatusOk , ErrorCode |
Exceptions | Class name in PascalCase with Error suffix | InvalidDataError , AuthenticationError |
invaliddataerror , authenticationerror |
File Uploads | Lowercase words separated by underscores (snake_case) | user_upload , image_file , uploaded_files |
UserUpload , ImageFile , UploadedFiles |
Function Arguments | Descriptive names, in lowercase and snake_case | user_id , start_time , end_time |
id , start , end |
Function/Methods | Lowercase words separated by underscores (snake_case) | get_user_data() , calculate_average() |
GetUserData() , calculateAverage() |
Global Variables | Use all lowercase with underscores (snake_case) | global_user , global_config |
GlobalUser , GlobalConfig |
Instance Methods | Lowercase words separated by underscores (snake_case) | get_user_info() , process_data() |
GetUserInfo() , ProcessData() |
Modules | Lowercase words separated by underscores (snake_case) | data_processor.py , user_manager.py |
DataProcessor.py , UserManager.py |
Packages | Lowercase words, no underscores | mypackage , utils , dataprocessing |
MyPackage , DataProcessing |
Private Variables | Leading underscore for "private" variables | _user_data , _car_model , _total_count |
user_data , car_model , total_count |
Properties | Lowercase words separated by underscores (snake_case) | user_age , car_model , account_balance |
UserAge , CarModel , AccountBalance |
Test Functions | Start with test_ and lowercase words separated by underscores (snake_case) | test_user_creation() , test_api_response() |
TestUserCreation() , TestAPIResponse() |
Variables | Lowercase words separated by underscores (snake_case) | user_age , car_model , total_count |
UserAge , CarModel , TotalCount |
- What are Python’s key features?
- Interpreted: Python is an interpreted language, which means the code is executed line by line.
- Dynamically Typed: You don’t need to declare the type of a variable explicitly.
- Easy to Learn: Python has a simple and readable syntax.
- Object-Oriented: Python supports object-oriented programming principles.
- Cross-Platform: Python is available on various platforms, such as Windows, Linux, and macOS.
- What is the difference between list and tuple in Python?
- List: A list is mutable, meaning its elements can be changed after creation. It uses square brackets [] (e.g., my_list = [1, 2, 3]).
- Tuple: A tuple is immutable, meaning its elements cannot be modified after creation. It uses parentheses () (e.g., my_tuple = (1, 2, 3)).
- What are Python’s data types?
int
(integer)float
(floating-point number)str
(string)list
(list of elements)tuple
(immutable list)set
(unordered collection of unique elements)dict
(dictionary, key-value pairs)bool
(boolean: True or False)None
(represents absence of value)
- What is the purpose of the self keyword in Python?
self
is used to refer to the instance of the current object within a class. It is a reference to the current object and allows access to its attributes and methods. It’s the first parameter in instance methods of a class.
- What is a lambda function in Python?
- A lambda function is a small anonymous function defined using the lambda keyword. It can take any number of arguments but can only have one expression. It’s often used for short, throwaway functions.
- What is list comprehension in Python?
- List comprehension is a concise way to create lists in Python. It allows you to generate a new list by applying an expression to each item in an existing list or iterable.
- Explain the difference between
deepcopy()
andcopy()
in Python.copy()
: Creates a shallow copy of an object. For mutable objects, changes made to nested elements in the copied object will affect the original object.deepcopy()
: Creates a deep copy of an object, meaning it recursively copies all nested objects. Changes to the copied object will not affect the original object.
- What is a decorator in Python?
- A decorator is a function that modifies the behavior of another function or method. It is applied using the @decorator_name syntax.
- What are Python’s memory management strategies?
- Memory Manager: Python has an automatic memory management system, which includes the Python Memory Manager, Garbage Collection, and Reference Counting.
- Reference Counting: Python keeps track of the number of references to an object, and when the reference count drops to zero, the object is deleted.
- Garbage Collection: Python automatically removes unused objects through a process known as garbage collection using the cyclic garbage collector.
- What is the Global Interpreter Lock (GIL) in Python?
- The Global Interpreter Lock (GIL) is a mutex that protects access to Python objects, ensuring that only one thread can execute Python bytecode at a time. This can limit the performance of multi-threaded Python programs, especially on multi-core machines.
- Explain Python’s yield keyword and how it works.
- The
yield
keyword is used in a function to turn it into a generator. A generator is a special type of iterator that yields values one at a time using theyield
keyword instead of returning them all at once.
- The
- What are metaclasses in Python?
- A metaclass is a class of a class. It defines the behavior of classes themselves, controlling the creation and customization of class objects. You can use metaclasses to modify class instantiation, inheritance, or method resolution order.
- What is the difference between
is
and==
in Python?is
: Checks if two variables point to the same object in memory (identity comparison).==
: Checks if the values of two variables are equal (value comparison).
- What is the purpose of
__init__()
in Python classes?__init__()
is the constructor method in Python classes. It is automatically called when an instance of the class is created and is used to initialize the object’s attributes.
- What is the purpose of the pass statement in Python?
- The pass statement is a placeholder that does nothing. It’s used when a statement is syntactically required but you don’t want to perform any action.
- What are Python’s built-in data structures?
List
: Ordered collection of items, can hold different types of data.Tuple
: Immutable sequence of elements.Set
: Unordered collection of unique items.Dictionary
: Collection of key-value pairs.
- How do you handle exceptions in Python?
- Python uses
try
,except
,else
, andfinally
blocks to handle exceptions. The try block is used to wrap code that may raise an exception, and the except block catches and handles the exception.
- Python uses
- What is the difference between
range()
andxrange()
in Python 2.x?- In Python 2.x,
range()
returns a list, whilexrange()
returns an iterator (generating values one at a time). In Python 3.x, range() behaves likexrange()
from Python 2.x and returns an iterator, soxrange()
no longer exists.
- In Python 2.x,
- What is Python’s with statement?
- The
with
statement is used to wrap the execution of a block of code within methods defined by a context manager. It ensures that resources are properly managed (like file handling or network connections) and automatically cleans up after execution.
- The