Functions: def, Arguments, *args, **kwargs
ফাংশন — def, আর্গুমেন্ট, *args, **kwargs
1. Why Functions?
A function is a named block of reusable code. Instead of writing the same logic again and again, you write it once inside a function, give it a name, and then call it whenever needed. Functions are the first and most important abstraction tool in any programming language — they let a program stay small in size while growing in capability.
Python function গুলোকে first-class citizens হিসেবে ধরা হয় — এদেরকে variable-এ রাখা যায়, argument হিসেবে পাস করা যায়, এবং return করা যায়।
2. Defining a Function with def
Python-এ function লেখা হয় def keyword দিয়ে। গঠনটি অত্যন্ত সরল:
def greet(name):
# docstring — describes what the function does
"""Return a friendly greeting for the given name."""
return f"Hello, {name}!"
print(greet("Arif"))
print(greet("Bangladesh"))
def keyword দিয়ে function-এর নাম ও parameter গুলো লিখুন। return statement function থেকে একটি মান ফেরত দেয়। যদি return না লেখেন, Python স্বয়ংক্রিয়ভাবে None return করে।
3. Positional vs Keyword Arguments
When you call a function, you can pass arguments by position (order matters) or by keyword (by name, order does not matter). Keyword arguments make your code much more readable.
def describe_pet(name, species, age):
return f"{name} is a {age}-year-old {species}."
# positional — order matters
print(describe_pet("Tommy", "dog", 3))
# keyword — order does not matter, clearer at call site
print(describe_pet(species="cat", age=2, name="Mia"))
# mixed — positional first, then keyword
print(describe_pet("Ruby", age=5, species="parrot"))
4. Default Arguments — এবং একটি বিখ্যাত Trap
আপনি function-এর parameter-এ default value দিতে পারেন। call করার সময় সেই argument না দিলে default-ই ব্যবহৃত হয়।
def power(base, exponent=2):
return base ** exponent
print(power(5)) # 25 — default exponent=2
print(power(5, 3)) # 125
print(power(base=2, exponent=10)) # 1024
list, dict, set) as a default argument. The default is evaluated once at function definition, not on every call — so the list is shared across all calls.
সতর্কতা: default argument হিসেবে
list, dict বা অন্য কোনো mutable object কখনোই ব্যবহার করবেন না — এটি function define হওয়ার সময় একবার তৈরি হয় এবং সব call-এ একই object reuse হয়। পরিবর্তে None ব্যবহার করুন।
# ❌ WRONG — shared list across calls
def bad_append(item, bag=[]):
bag.append(item)
return bag
print(bad_append(1)) # [1]
print(bad_append(2)) # [1, 2] ← surprise!
# ✅ CORRECT — use None sentinel
def good_append(item, bag=None):
if bag is None:
bag = []
bag.append(item)
return bag
print(good_append(1)) # [1]
print(good_append(2)) # [2]
5. *args and **kwargs — Variable Number of Arguments
Sometimes you don't know in advance how many arguments will be passed. Python has two special syntaxes for this:
*args collects extra positional arguments into a tuple, and **kwargs collects extra keyword
arguments into a dict.
def total(*args):
# args is a tuple of whatever was passed
return sum(args)
print(total(1, 2, 3)) # 6
print(total(10, 20, 30, 40, 50)) # 150
def profile(**kwargs):
# kwargs is a dict of name=value pairs
for key, value in kwargs.items():
print(f"{key}: {value}")
profile(name="Rafi", age=21, city="Dhaka")
# you can combine both
def describe(label, *items, **meta):
print(f"{label}: {items} meta={meta}")
describe("Fruits", "apple", "mango", color="mixed", count=2)
*args যেকোনো সংখ্যক positional argument একটি tuple-এ সংগ্রহ করে। **kwargs যেকোনো সংখ্যক keyword argument একটি dict-এ সংগ্রহ করে। নাম দুটি convention — চাইলে *nums বা **options লেখা যায়। তবে *args/**kwargs লিখলে সবাই সাথে সাথে বোঝে।
6. Scope — The LEGB Rule
When Python sees a name (like x), it searches four scopes in this exact order:
Local → Enclosing → Global → Built-in. This is called the LEGB rule.
x = "global x" # G
def outer():
x = "enclosing x" # E
def inner():
x = "local x" # L
print(x)
inner()
outer() # local x
print(x) # global x
7. Vocabulary (শব্দভাণ্ডার)
| Term | Meaning | বাংলায় |
|---|---|---|
| Parameter | A variable in the function definition. | Function define করার সময় লেখা variable। |
| Argument | A value passed at call time. | Function call করার সময় পাস করা মান। |
| Return value | The value produced by return. | return statement যা দেয়। |
| Docstring | A string literal as the first statement in a function — used as documentation. | Function-এর প্রথম string literal — ডকুমেন্টেশন হিসেবে ব্যবহার হয়। |
*args | Packs extra positional args into a tuple. | অতিরিক্ত positional argument-গুলো tuple-এ রাখে। |
**kwargs | Packs extra keyword args into a dict. | অতিরিক্ত keyword argument-গুলো dict-এ রাখে। |
| LEGB | Scope lookup order. | Name খোঁজার ক্রম। |
8. Practice Problems
-
Write a function
is_even(n)that returnsTrueifnis even.একটি functionis_even(n)লিখুন যাneven হলেTruereturn করবে।✨ Show Answer (উত্তর দেখুন)
ans1.pydef is_even(n): return n % 2 == 0 print(is_even(4)) # True print(is_even(7)) # False -
Write
average(*nums)that returns the mean of any number of values.average(*nums)লিখুন যা যেকোনো সংখ্যক মানের গড় return করবে।✨ Show Answer (উত্তর দেখুন)
ans2.pydef average(*nums): if not nums: return 0 return sum(nums) / len(nums) print(average(10, 20, 30)) print(average(5, 9, 11, 13, 17)) -
Why is
def f(x, lst=[]):considered a bug-prone pattern? Explain in 2–3 lines.কেনdef f(x, lst=[]):লেখা bug-prone? ২–৩ লাইনে ব্যাখ্যা করুন।✨ Show Answer
The default list is evaluated once when the function is defined — it becomes a shared object across every call that does not pass
lst. Anylst.append(...)persists between calls. Uselst=Noneand create a new list inside the body instead.Default list function define হওয়ার সময় একবারই তৈরি হয় এবং সব call এর মধ্যে shared থাকে। তাই
lst.appendপরবর্তী call-এও থেকে যায়। সমাধান:lst=Noneলিখে body-এর ভেতরে নতুন list তৈরি করুন। -
Write
build_url(base, **params)that builds a query-string URL, e.g.build_url("https://api.x", q="python", page=2).build_url(base, **params)লিখুন যা query-string সহ একটি URL তৈরি করবে।✨ Show Answer
ans4.pydef build_url(base, **params): if not params: return base query = "&".join(f"{k}={v}" for k, v in params.items()) return f"{base}?{query}" print(build_url("https://api.x", q="python", page=2)) -
Write a function
bmi(weight_kg, height_m)and return a category: "Underweight", "Normal", "Overweight", "Obese".bmi(weight_kg, height_m)function লিখুন যা BMI বের করে category return করবে।✨ Show Answer
ans5.pydef bmi(weight_kg, height_m): value = weight_kg / (height_m ** 2) if value < 18.5: category = "Underweight" elif value < 25: category = "Normal" elif value < 30: category = "Overweight" else: category = "Obese" return round(value, 1), category print(bmi(72, 1.75))
Summary — Module 11
Functions are Python's primary abstraction. You define them with def, return values with
return, and call them by name. Arguments can be positional or keyword; parameters can have
defaults — just avoid mutable defaults. Use *args and **kwargs for
variadic calls. Name lookup follows the LEGB rule: Local, Enclosing, Global, Built-in.
def দিয়ে define করুন, return দিয়ে মান ফেরত দিন। Argument positional বা keyword হতে পারে, default value দিতে পারেন — তবে mutable default এড়িয়ে যান। *args/**kwargs দিয়ে variadic function লিখুন। Name খোঁজার ক্রম — LEGB।