Category | Keywords |
---|---|
Control Flow | if , else , elif , while , for , break , continue , pass |
Boolean Logic | True , False , and , or , not , is , in |
Functions | def , return , lambda , yield , global , nonlocal |
Classes & OOP | class , del , self , super |
Exception Handling | try , except , finally , raise , assert |
Variable Control | None , as , with , from , import |
Miscellaneous | await , async , match , case (Python 3.10+) |
Declarations | True , False , None |
import keyword
print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
A function is a block of reusable code that performs a specific task. Functions help in:
Built-in Functions: Already available in Python.
🔹 Examples: print()
, len()
, type()
, sum()
, range()
User-defined Functions: Functions you write yourself using def
keyword.
Lambda Functions: Short anonymous functions created using lambda
keyword.
def greet():
print("Hello, World!")
greet() # Output: Hello, World!
def greet(name):
print(f"Hello, {name}!")
greet("Purushotham") # Output: Hello, Purushotham!
def add(x, y):
return x + y
result = add(5, 3)
print(result) # Output: 8
def greet(name="User"):
print(f"Hello, {name}!")
greet() # Output: Hello, User!
greet("AI Bro") # Output: Hello, AI Bro!
*args
→ multiple positional arguments (tuple)**kwargs
→ multiple keyword arguments (dict)def show_items(*args):
for item in args:
print(item)
show_items("Pen", "Notebook", "Pencil")
Short, anonymous function (used for simple operations)
square = lambda x: x**2
print(square(5)) # Output: 25
# Documentation (also called a docstring) is a special string that explains what a function does, its parameters, return values, and usage.
def add(a, b):
"""
Adds two numbers.
Parameters:
a (int or float): First number
b (int or float): Second number
Returns:
int or float: The sum of a and b
"""
return a + b
# Accessing Documentation
print(add.__doc__)
Adds two numbers. Parameters: a (int or float): First number b (int or float): Second number Returns: int or float: The sum of a and b
help(add)
Help on function add in module __main__: add(a, b) Adds two numbers. Parameters: a (int or float): First number b (int or float): Second number Returns: int or float: The sum of a and b
help(str)
Help on class str in module builtins: class str(object) | str(object='') -> str | str(bytes_or_buffer[, encoding[, errors]]) -> str | | Create a new string object from the given object. If encoding or | errors is specified, then the object must expose a data buffer | that will be decoded using the given encoding and error handler. | Otherwise, returns the result of object.__str__() (if defined) | or repr(object). | encoding defaults to sys.getdefaultencoding(). | errors defaults to 'strict'. | | Methods defined here: | | __add__(self, value, /) | Return self+value. | | __contains__(self, key, /) | Return key in self. | | __eq__(self, value, /) | Return self==value. | | __format__(self, format_spec, /) | Return a formatted version of the string as described by format_spec. | | __ge__(self, value, /) | Return self>=value. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __getitem__(self, key, /) | Return self[key]. | | __getnewargs__(...) | | __gt__(self, value, /) | Return self>value. | | __hash__(self, /) | Return hash(self). | | __iter__(self, /) | Implement iter(self). | | __le__(self, value, /) | Return self<=value. | | __len__(self, /) | Return len(self). | | __lt__(self, value, /) | Return self<value. | | __mod__(self, value, /) | Return self%value. | | __mul__(self, value, /) | Return self*value. | | __ne__(self, value, /) | Return self!=value. | | __repr__(self, /) | Return repr(self). | | __rmod__(self, value, /) | Return value%self. | | __rmul__(self, value, /) | Return value*self. | | __sizeof__(self, /) | Return the size of the string in memory, in bytes. | | __str__(self, /) | Return str(self). | | capitalize(self, /) | Return a capitalized version of the string. | | More specifically, make the first character have upper case and the rest lower | case. | | casefold(self, /) | Return a version of the string suitable for caseless comparisons. | | center(self, width, fillchar=' ', /) | Return a centered string of length width. | | Padding is done using the specified fill character (default is a space). | | count(...) | S.count(sub[, start[, end]]) -> int | | Return the number of non-overlapping occurrences of substring sub in | string S[start:end]. Optional arguments start and end are | interpreted as in slice notation. | | encode(self, /, encoding='utf-8', errors='strict') | Encode the string using the codec registered for encoding. | | encoding | The encoding in which to encode the string. | errors | The error handling scheme to use for encoding errors. | The default is 'strict' meaning that encoding errors raise a | UnicodeEncodeError. Other possible values are 'ignore', 'replace' and | 'xmlcharrefreplace' as well as any other name registered with | codecs.register_error that can handle UnicodeEncodeErrors. | | endswith(...) | S.endswith(suffix[, start[, end]]) -> bool | | Return True if S ends with the specified suffix, False otherwise. | With optional start, test S beginning at that position. | With optional end, stop comparing S at that position. | suffix can also be a tuple of strings to try. | | expandtabs(self, /, tabsize=8) | Return a copy where all tab characters are expanded using spaces. | | If tabsize is not given, a tab size of 8 characters is assumed. | | find(...) | S.find(sub[, start[, end]]) -> int | | Return the lowest index in S where substring sub is found, | such that sub is contained within S[start:end]. Optional | arguments start and end are interpreted as in slice notation. | | Return -1 on failure. | | format(...) | S.format(*args, **kwargs) -> str | | Return a formatted version of S, using substitutions from args and kwargs. | The substitutions are identified by braces ('{' and '}'). | | format_map(...) | S.format_map(mapping) -> str | | Return a formatted version of S, using substitutions from mapping. | The substitutions are identified by braces ('{' and '}'). | | index(...) | S.index(sub[, start[, end]]) -> int | | Return the lowest index in S where substring sub is found, | such that sub is contained within S[start:end]. Optional | arguments start and end are interpreted as in slice notation. | | Raises ValueError when the substring is not found. | | isalnum(self, /) | Return True if the string is an alpha-numeric string, False otherwise. | | A string is alpha-numeric if all characters in the string are alpha-numeric and | there is at least one character in the string. | | isalpha(self, /) | Return True if the string is an alphabetic string, False otherwise. | | A string is alphabetic if all characters in the string are alphabetic and there | is at least one character in the string. | | isascii(self, /) | Return True if all characters in the string are ASCII, False otherwise. | | ASCII characters have code points in the range U+0000-U+007F. | Empty string is ASCII too. | | isdecimal(self, /) | Return True if the string is a decimal string, False otherwise. | | A string is a decimal string if all characters in the string are decimal and | there is at least one character in the string. | | isdigit(self, /) | Return True if the string is a digit string, False otherwise. | | A string is a digit string if all characters in the string are digits and there | is at least one character in the string. | | isidentifier(self, /) | Return True if the string is a valid Python identifier, False otherwise. | | Call keyword.iskeyword(s) to test whether string s is a reserved identifier, | such as "def" or "class". | | islower(self, /) | Return True if the string is a lowercase string, False otherwise. | | A string is lowercase if all cased characters in the string are lowercase and | there is at least one cased character in the string. | | isnumeric(self, /) | Return True if the string is a numeric string, False otherwise. | | A string is numeric if all characters in the string are numeric and there is at | least one character in the string. | | isprintable(self, /) | Return True if the string is printable, False otherwise. | | A string is printable if all of its characters are considered printable in | repr() or if it is empty. | | isspace(self, /) | Return True if the string is a whitespace string, False otherwise. | | A string is whitespace if all characters in the string are whitespace and there | is at least one character in the string. | | istitle(self, /) | Return True if the string is a title-cased string, False otherwise. | | In a title-cased string, upper- and title-case characters may only | follow uncased characters and lowercase characters only cased ones. | | isupper(self, /) | Return True if the string is an uppercase string, False otherwise. | | A string is uppercase if all cased characters in the string are uppercase and | there is at least one cased character in the string. | | join(self, iterable, /) | Concatenate any number of strings. | | The string whose method is called is inserted in between each given string. | The result is returned as a new string. | | Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs' | | ljust(self, width, fillchar=' ', /) | Return a left-justified string of length width. | | Padding is done using the specified fill character (default is a space). | | lower(self, /) | Return a copy of the string converted to lowercase. | | lstrip(self, chars=None, /) | Return a copy of the string with leading whitespace removed. | | If chars is given and not None, remove characters in chars instead. | | partition(self, sep, /) | Partition the string into three parts using the given separator. | | This will search for the separator in the string. If the separator is found, | returns a 3-tuple containing the part before the separator, the separator | itself, and the part after it. | | If the separator is not found, returns a 3-tuple containing the original string | and two empty strings. | | removeprefix(self, prefix, /) | Return a str with the given prefix string removed if present. | | If the string starts with the prefix string, return string[len(prefix):]. | Otherwise, return a copy of the original string. | | removesuffix(self, suffix, /) | Return a str with the given suffix string removed if present. | | If the string ends with the suffix string and that suffix is not empty, | return string[:-len(suffix)]. Otherwise, return a copy of the original | string. | | replace(self, old, new, count=-1, /) | Return a copy with all occurrences of substring old replaced by new. | | count | Maximum number of occurrences to replace. | -1 (the default value) means replace all occurrences. | | If the optional argument count is given, only the first count occurrences are | replaced. | | rfind(...) | S.rfind(sub[, start[, end]]) -> int | | Return the highest index in S where substring sub is found, | such that sub is contained within S[start:end]. Optional | arguments start and end are interpreted as in slice notation. | | Return -1 on failure. | | rindex(...) | S.rindex(sub[, start[, end]]) -> int | | Return the highest index in S where substring sub is found, | such that sub is contained within S[start:end]. Optional | arguments start and end are interpreted as in slice notation. | | Raises ValueError when the substring is not found. | | rjust(self, width, fillchar=' ', /) | Return a right-justified string of length width. | | Padding is done using the specified fill character (default is a space). | | rpartition(self, sep, /) | Partition the string into three parts using the given separator. | | This will search for the separator in the string, starting at the end. If | the separator is found, returns a 3-tuple containing the part before the | separator, the separator itself, and the part after it. | | If the separator is not found, returns a 3-tuple containing two empty strings | and the original string. | | rsplit(self, /, sep=None, maxsplit=-1) | Return a list of the substrings in the string, using sep as the separator string. | | sep | The separator used to split the string. | | When set to None (the default value), will split on any whitespace | character (including \n \r \t \f and spaces) and will discard | empty strings from the result. | maxsplit | Maximum number of splits. | -1 (the default value) means no limit. | | Splitting starts at the end of the string and works to the front. | | rstrip(self, chars=None, /) | Return a copy of the string with trailing whitespace removed. | | If chars is given and not None, remove characters in chars instead. | | split(self, /, sep=None, maxsplit=-1) | Return a list of the substrings in the string, using sep as the separator string. | | sep | The separator used to split the string. | | When set to None (the default value), will split on any whitespace | character (including \n \r \t \f and spaces) and will discard | empty strings from the result. | maxsplit | Maximum number of splits. | -1 (the default value) means no limit. | | Splitting starts at the front of the string and works to the end. | | Note, str.split() is mainly useful for data that has been intentionally | delimited. With natural text that includes punctuation, consider using | the regular expression module. | | splitlines(self, /, keepends=False) | Return a list of the lines in the string, breaking at line boundaries. | | Line breaks are not included in the resulting list unless keepends is given and | true. | | startswith(...) | S.startswith(prefix[, start[, end]]) -> bool | | Return True if S starts with the specified prefix, False otherwise. | With optional start, test S beginning at that position. | With optional end, stop comparing S at that position. | prefix can also be a tuple of strings to try. | | strip(self, chars=None, /) | Return a copy of the string with leading and trailing whitespace removed. | | If chars is given and not None, remove characters in chars instead. | | swapcase(self, /) | Convert uppercase characters to lowercase and lowercase characters to uppercase. | | title(self, /) | Return a version of the string where each word is titlecased. | | More specifically, words start with uppercased characters and all remaining | cased characters have lower case. | | translate(self, table, /) | Replace each character in the string using the given translation table. | | table | Translation table, which must be a mapping of Unicode ordinals to | Unicode ordinals, strings, or None. | | The table must implement lookup/indexing via __getitem__, for instance a | dictionary or list. If this operation raises LookupError, the character is | left untouched. Characters mapped to None are deleted. | | upper(self, /) | Return a copy of the string converted to uppercase. | | zfill(self, width, /) | Pad a numeric string with zeros on the left, to fill a field of the given width. | | The string is never truncated. | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) | Create and return a new object. See help(type) for accurate signature. | | maketrans(...) | Return a translation table usable for str.translate(). | | If there is only one argument, it must be a dictionary mapping Unicode | ordinals (integers) or characters to Unicode ordinals, strings or None. | Character keys will be then converted to ordinals. | If there are two arguments, they must be strings of equal length, and | in the resulting dictionary, each character in x will be mapped to the | character at the same position in y. If there is a third argument, it | must be a string, whose characters will be mapped to None in the result.
help(list)
Help on class list in module builtins: class list(object) | list(iterable=(), /) | | Built-in mutable sequence. | | If no argument is given, the constructor creates a new empty list. | The argument must be an iterable if specified. | | Methods defined here: | | __add__(self, value, /) | Return self+value. | | __contains__(self, key, /) | Return key in self. | | __delitem__(self, key, /) | Delete self[key]. | | __eq__(self, value, /) | Return self==value. | | __ge__(self, value, /) | Return self>=value. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __getitem__(...) | x.__getitem__(y) <==> x[y] | | __gt__(self, value, /) | Return self>value. | | __iadd__(self, value, /) | Implement self+=value. | | __imul__(self, value, /) | Implement self*=value. | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | __iter__(self, /) | Implement iter(self). | | __le__(self, value, /) | Return self<=value. | | __len__(self, /) | Return len(self). | | __lt__(self, value, /) | Return self<value. | | __mul__(self, value, /) | Return self*value. | | __ne__(self, value, /) | Return self!=value. | | __repr__(self, /) | Return repr(self). | | __reversed__(self, /) | Return a reverse iterator over the list. | | __rmul__(self, value, /) | Return value*self. | | __setitem__(self, key, value, /) | Set self[key] to value. | | __sizeof__(self, /) | Return the size of the list in memory, in bytes. | | append(self, object, /) | Append object to the end of the list. | | clear(self, /) | Remove all items from list. | | copy(self, /) | Return a shallow copy of the list. | | count(self, value, /) | Return number of occurrences of value. | | extend(self, iterable, /) | Extend list by appending elements from the iterable. | | index(self, value, start=0, stop=9223372036854775807, /) | Return first index of value. | | Raises ValueError if the value is not present. | | insert(self, index, object, /) | Insert object before index. | | pop(self, index=-1, /) | Remove and return item at index (default last). | | Raises IndexError if list is empty or index is out of range. | | remove(self, value, /) | Remove first occurrence of value. | | Raises ValueError if the value is not present. | | reverse(self, /) | Reverse *IN PLACE*. | | sort(self, /, *, key=None, reverse=False) | Sort the list in ascending order and return None. | | The sort is in-place (i.e. the list itself is modified) and stable (i.e. the | order of two equal elements is maintained). | | If a key function is given, apply it once to each list item and sort them, | ascending or descending, according to their function values. | | The reverse flag can be set to sort in descending order. | | ---------------------------------------------------------------------- | Class methods defined here: | | __class_getitem__(...) | See PEP 585 | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __hash__ = None
help(dict)
Help on class dict in module builtins: class dict(object) | dict() -> new empty dictionary | dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs | dict(iterable) -> new dictionary initialized as if via: | d = {} | for k, v in iterable: | d[k] = v | dict(**kwargs) -> new dictionary initialized with the name=value pairs | in the keyword argument list. For example: dict(one=1, two=2) | | Built-in subclasses: | StgDict | | Methods defined here: | | __contains__(self, key, /) | True if the dictionary has the specified key, else False. | | __delitem__(self, key, /) | Delete self[key]. | | __eq__(self, value, /) | Return self==value. | | __ge__(self, value, /) | Return self>=value. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __getitem__(...) | x.__getitem__(y) <==> x[y] | | __gt__(self, value, /) | Return self>value. | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | __ior__(self, value, /) | Return self|=value. | | __iter__(self, /) | Implement iter(self). | | __le__(self, value, /) | Return self<=value. | | __len__(self, /) | Return len(self). | | __lt__(self, value, /) | Return self<value. | | __ne__(self, value, /) | Return self!=value. | | __or__(self, value, /) | Return self|value. | | __repr__(self, /) | Return repr(self). | | __reversed__(self, /) | Return a reverse iterator over the dict keys. | | __ror__(self, value, /) | Return value|self. | | __setitem__(self, key, value, /) | Set self[key] to value. | | __sizeof__(...) | D.__sizeof__() -> size of D in memory, in bytes | | clear(...) | D.clear() -> None. Remove all items from D. | | copy(...) | D.copy() -> a shallow copy of D | | get(self, key, default=None, /) | Return the value for key if key is in the dictionary, else default. | | items(...) | D.items() -> a set-like object providing a view on D's items | | keys(...) | D.keys() -> a set-like object providing a view on D's keys | | pop(...) | D.pop(k[,d]) -> v, remove specified key and return the corresponding value. | | If the key is not found, return the default if given; otherwise, | raise a KeyError. | | popitem(self, /) | Remove and return a (key, value) pair as a 2-tuple. | | Pairs are returned in LIFO (last-in, first-out) order. | Raises KeyError if the dict is empty. | | setdefault(self, key, default=None, /) | Insert key with a value of default if key is not in the dictionary. | | Return the value for key if key is in the dictionary, else default. | | update(...) | D.update([E, ]**F) -> None. Update D from dict/iterable E and F. | If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] | If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v | In either case, this is followed by: for k in F: D[k] = F[k] | | values(...) | D.values() -> an object providing a view on D's values | | ---------------------------------------------------------------------- | Class methods defined here: | | __class_getitem__(...) | See PEP 585 | | fromkeys(iterable, value=None, /) | Create a new dictionary with keys from iterable and values set to value. | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __hash__ = None
A Higher-Order Function is a function that:
In short:
"Functions that work with other functions."
def greet(name):
return f"Hello, {name}!"
def call_func(func, value):
return func(value)
print(call_func(greet, "Purushotham"))
# Output: Hello, Purushotham!
def outer(x):
def inner(y):
return x + y
return inner
add5 = outer(5)
print(add5(10)) # Output: 15
Python provides several built-in higher-order functions:
map(function, iterable)
Applies a function to every item in an iterable.
nums = [1, 2, 3, 4]
squares = list(map(lambda x: x**2, nums))
print(squares) # Output: [1, 4, 9, 16]
filter(function, iterable)
Filters items where the function returns True
.
nums = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # Output: [2, 4]
reduce(function, iterable)
Applies a function cumulatively to reduce the iterable to a single value.
Requires:
from functools import reduce
from functools import reduce
nums = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, nums)
print(product) # Output: 24
from functools import reduce
nums = [1, 2, 3, 4, 5]
# Filter even numbers, square them, then sum the result
result = reduce(lambda x, y: x + y,
map(lambda x: x**2,
filter(lambda x: x % 2 == 0, nums)))
print(result) # Output: 20 (2² + 4² = 4 + 16)
A decorator modifies or enhances the behavior of a function without changing its code.
def my_decorator(func):
def wrapper():
print("Before call")
func()
print("After call")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
A closure remembers the environment in which it was created.
def outer(x):
def inner(y):
return x + y
return inner
add5 = outer(5)
print(add5(3)) # Output: 8
In Python, functions can be:
def shout(text):
return text.upper()
def whisper(text):
return text.lower()
def greet(func):
print(func("Hello"))
greet(shout)
greet(whisper)
*args
and `kwargs` - Advanced Use**def demo(*args, **kwargs):
print("Positional:", args)
print("Keyword:", kwargs)
demo(1, 2, 3, name="Purushotham", job="ML")
functools.partial
)Fix certain arguments of a function and generate a new function.
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
print(square(5)) # Output: 25
from functools import reduce
nums = [1, 2, 3, 4]
# map: apply function to each item
squares = list(map(lambda x: x**2, nums))
# filter: filter elements
even = list(filter(lambda x: x % 2 == 0, nums))
# reduce: accumulate results
product = reduce(lambda x, y: x * y, nums)
yield
)Efficient memory handling for large sequences.
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for num in count_up_to(5):
print(num)
Improves readability and debugging.
def greet(name: str) -> str:
return f"Hello, {name}"
Use built-in tools to examine functions:
def sample(x: int) -> int:
return x * 2
print(sample.__name__)
print(sample.__annotations__)
print(callable(sample))
from functools import lru_cache
@lru_cache(maxsize=1000)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
Object-Oriented Programming (OOP) is a programming paradigm centered around objects and classes. Python supports OOP and allows you to model real-world entities.
Concept | Description |
---|---|
Class | Blueprint for creating objects |
Object | Instance of a class |
Constructor | __init__ method used to initialize objects |
Encapsulation | Hiding internal data using access specifiers (_ , __ ) |
Abstraction | Hiding unnecessary implementation details |
Inheritance | One class (child) inherits properties from another (parent) |
Polymorphism | Ability to take many forms (method overriding/overloading) |
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
def drive(self):
print(f"{self.color} {self.brand} is driving.")
my_car = Car("Toyota", "Red")
my_car.drive() # Output: Red Toyota is driving.
Protecting internal data.
class BankAccount:
def __init__(self, balance):
self.__balance = balance # private variable
def get_balance(self):
return self.__balance
acc = BankAccount(5000)
print(acc.get_balance()) # ✅ 5000
# print(acc.__balance) # ❌ Error: private attribute
Child class inherits from parent.
class Animal:
def sound(self):
print("Some sound")
class Dog(Animal):
def sound(self):
print("Bark")
d = Dog()
d.sound() # Output: Bark
Same method name, different behavior.
class Bird:
def speak(self):
print("Tweet")
class Parrot(Bird):
def speak(self):
print("Squawk")
def make_sound(bird):
bird.speak()
make_sound(Parrot()) # Output: Squawk
Hide implementation, show interface (via abstract classes).
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
c = Circle(5)
print(c.area()) # Output: 78.5
Concept | Python Feature |
---|---|
Class/Object | class , __init__ , object |
Inheritance | class Child(Parent) |
Polymorphism | Method Overriding |
Encapsulation | _protected , __private vars |
Abstraction | ABC , abstractmethod |
Python allows us to create, read, write, and delete files using built-in functions like open()
, read()
, write()
, and close()
.
open()
file = open("filename.txt", "mode")
Common modes:
Mode | Description |
---|---|
'r' |
Read (default), file must exist |
'w' |
Write, creates or overwrites |
'a' |
Append, creates if not exists |
'x' |
Exclusive create, fails if exists |
'b' |
Binary mode (rb , wb , etc.) |
't' |
Text mode (default, used with others) |
# Read entire content
with open("sample.txt", "r") as f:
content = f.read()
print(content)
# Read line by line
with open("sample.txt", "r") as f:
for line in f:
print(line.strip())
# Read specific number of characters
with open("sample.txt", "r") as f:
print(f.read(5)) # Reads 5 characters
# Overwrites the file if it exists
with open("output.txt", "w") as f:
f.write("Hello, world!\n")
f.write("Second line.\n")
with open("output.txt", "a") as f:
f.write("This line will be added.\n")
# Fails if the file already exists
with open("newfile.txt", "x") as f:
f.write("Created new file.")
import os
if os.path.exists("oldfile.txt"):
os.remove("oldfile.txt")
else:
print("File does not exist")
import os
print(os.path.exists("myfile.txt")) # True/False
print(os.path.isfile("myfile.txt")) # True if file
print(os.path.isdir("myfolder")) # True if folder
Method | Description |
---|---|
read() |
Reads entire file |
readline() |
Reads a single line |
readlines() |
Returns list of lines |
write() |
Writes to file |
writelines() |
Writes list of strings |
close() |
Closes the file |
Note: Use with open(...)
to auto-close the file.
Exception: An error that occurs during the execution of a program, disrupting the normal flow.
To gracefully handle errors and keep the program from crashing.
try:
# Code that may raise an exception
x = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
else:
print("No exceptions occurred.")
finally:
print("Always runs.")
Block | Purpose |
---|---|
try |
Code that may raise an exception |
except |
Block to catch and handle exceptions |
else |
Runs only if no exception occurs |
finally |
Runs no matter what (used for cleanup like closing files/db) |
try:
x = int("abc")
except (ValueError, TypeError) as e:
print(f"Error occurred: {e}")
Not recommended unless you're logging or debugging.
try:
something()
except Exception as e:
print("Error:", e)
You can raise exceptions manually using raise
.
def divide(a, b):
if b == 0:
raise ValueError("Denominator cannot be zero.")
return a / b
Exception | Description |
---|---|
ZeroDivisionError |
Division by zero |
ValueError |
Wrong value (e.g., int('abc') ) |
TypeError |
Operation on incompatible types |
IndexError |
Index out of range (e.g., list[10]) |
KeyError |
Accessing a missing dictionary key |
FileNotFoundError |
File not found during file operations |
AttributeError |
Invalid attribute access |
ImportError |
Error in importing module |
NameError |
Variable not defined |
StopIteration |
Raised by next() in loops when no item exists |
KeyboardInterrupt |
Interrupt by user using Ctrl+C |
MemoryError |
Out of memory |
AssertionError |
When assert statement fails |
try:
f = open("data.txt")
content = f.read()
except FileNotFoundError:
print("File not found.")
finally:
print("Operation complete.")
You can define your own error types by extending Exception
.
class MyCustomError(Exception):
pass
raise MyCustomError("Something went wrong.")
try:
risky_code()
except SpecificError:
handle_it()
except AnotherError as e:
handle_with_info(e)
else:
no_errors()
finally:
always_runs()
class TooYoungError(Exception):
pass
def register(age):
if age < 18:
raise TooYoungError("Must be 18+ to register.")
try:
register(16)
except TooYoungError as e:
print(e)
Debugging is the process of finding and fixing errors (bugs) in code.
Assertions are used to check if a condition is True at a specific point in the program.
If it’s False, Python throws an AssertionError
.
assert condition, "Optional error message"
x = 5
assert x > 0, "x must be positive"
If x = -1
, this will raise:
AssertionError: x must be positive
Used to catch logic errors early during development.
Don’t use assertions for user input validation in production — they can be disabled with python -O
.
A traceback is the stack trace showing where an error occurred.
Use the traceback
module:
import traceback
try:
1 / 0
except ZeroDivisionError:
tb_str = traceback.format_exc()
print("Traceback as string:\n", tb_str)
A flexible system for recording:
More powerful and configurable than print()
.
import logging
logging.basicConfig(level=logging.INFO)
logging.info("This is an info message.")
logging.warning("This is a warning.")
logging.error("Something went wrong.")
Level | Use Case |
---|---|
DEBUG | Detailed debugging info |
INFO | General app flow messages |
WARNING | Something unexpected happened |
ERROR | A serious problem occurred |
CRITICAL | Very serious error |
logging.basicConfig(
filename='app.log',
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logging.error("This goes to a file!")
try:
1 / 0
except ZeroDivisionError:
logging.exception("Exception occurred")
This prints both error message and full traceback!
import logging
logging.basicConfig(level=logging.INFO)
logging.info("This is an info message.")
logging.warning("This is a warning.")
logging.error("Something went wrong.")
WARNING:root:This is a warning. ERROR:root:Something went wrong.
logging.basicConfig(
filename='app.log',
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logging.error("This goes to a file!")
ERROR:root:This goes to a file!
A module is simply a Python file (.py
) containing variables, functions, classes, etc., that you can import and reuse in other Python programs.
Purpose: Helps organize code, improve reusability, and maintainability.
Type | Example |
---|---|
Built-in | math , os , sys , random |
User-defined | Your own .py files |
Third-party | Installed via pip like numpy , pandas , requests |
math
import math
print(math.sqrt(25)) # 5.0
print(math.pi) # 3.141592653589793
File: mymodule.py
# mymodule.py
def greet(name):
return f"Hello, {name}!"
pi = 3.14
Now use it in another file:
import mymodule
print(mymodule.greet("Purushotham"))
print(mymodule.pi)
import
Variants# import whole module
import math
math.sqrt(16)
# import specific function
from math import sqrt
sqrt(16)
# import with alias
import math as m
m.sqrt(16)
# import all (not recommended)
from math import *
__name__ == "__main__"
# module_test.py
def run():
print("Running test...")
if __name__ == "__main__":
run()
This ensures the block only runs if file is executed directly, not when imported.
Module | Use Case |
---|---|
math |
Mathematical operations |
random |
Random number generation |
datetime |
Date and time manipulation |
os |
OS-level operations (files, dirs) |
sys |
Command line args, interpreter info |
json |
Work with JSON data |
re |
Regular expressions |
time |
Timing, sleep functions |
pip install
)pip install requests
import requests
response = requests.get("https://api.github.com")
print(response.status_code)
import numpy as np
) for readability.from module import *
) in production.Project: Weather App
main.py
: user interfaceweather.py
: handles API requestsutils.py
: helper functions (formatting, error handling)All parts communicate via module imports.