அடிப்படை

Python-இல் செயல்பாடுகள்: def, return, வாதங்கள், *args மற்றும் **kwargs, lambda மற்றும் வகை குறிப்புகள்

புதுப்பிக்கப்பட்டது: · Skillaria.Top

Python-இல் செயல்பாடு என்பது def என்ற சொல்லால் அறிவிக்கப்படும், பெயருடன் கூடிய குறியீட்டுத் தொகுதி; அதை அடைப்புக்குறிகளுடன் பெயரால் அழைக்கலாம்; முடிவை return மூலம் திருப்பித் தரலாம். return இல்லையென்றால் செயல்பாடு None தரும். வாதங்கள் வரிசைப்படியோ பெயராலோ அனுப்பப்படும்; *args கூடுதல் நிலை மதிப்புகளை tuple-ஆகவும், **kwargs பெயரிட்ட மதிப்புகளை அகராதியாகவும் சேகரிக்கும்; lambda ஒரே வெளிப்பாட்டைக் கொண்ட குறுகிய பெயரில்லாச் செயல்பாடு.

Python-இல் செயல்பாடு என்பது பெயருடன் கூடிய குறியீட்டுத் துண்டு; அதை வெவ்வேறு உள்ளீடுகளுடன் எத்தனை முறையும் அழைக்கலாம். அது def சொல்லால் அறிவிக்கப்படும், அளவுருக்கள் மூலம் மதிப்புகளைப் பெறும், return மூலம் முடிவைத் தரும். நீண்ட நிரல் "சுவரை" தெளிவான, சரிபார்க்கக்கூடிய படிகளாக மாற்றுவதற்கான முக்கிய வழி இதுவே.

செயல்பாட்டை அறிவிப்பது: def

செயல்பாட்டு அறிவிப்பு def-உடன் தொடங்கும்; பின்னர் பெயர், அடைப்புக்குறிக்குள் அளவுருக்கள், பெருங்குடல். உடல் நான்கு இடைவெளி உள்தள்ளலில் எழுதப்படும் — Python-இல் உள்தள்ளல் அலங்காரம் அல்ல, தொடரியலின் ஒரு பகுதி.

def greet(name):
    """பயனருக்கான வாழ்த்தை திருப்பித் தருகிறது."""
    return f"வணக்கம், {name}!"

print(greet("அன்னா"))   # வணக்கம், அன்னா!

தலைப்புக்குப் பின் உடனே உள்ள மூன்று மேற்கோள்களிலான சரம் docstring — செயல்பாட்டின் ஆவணம். அதை help(greet) மற்றும் எடிட்டரின் குறிப்புகள் காட்டும். செயல்பாட்டுப் பெயர்கள் PEP 8 மரபின்படி snake_case-இல் எழுதப்படுகின்றன: add_expense, get_rate.

def greet(name): வரி செயல்பாட்டின் கையொப்பம் (signature) எனப்படும்: பெயரும் அளவுருப் பட்டியலும் (இருந்தால் annotations-உம்). கையொப்பத்திலிருந்தே உடலைப் பார்க்காமல் அதை எப்படி அழைப்பது என்று வாசகர் புரிந்துகொள்ளலாம்.

Python-இல் return என்ன செய்கிறது

return செயல்பாட்டை முடித்து, அதை அழைத்தவருக்கு மதிப்பைத் தரும். இயங்கிய return-க்குப் பின் உள்ள குறியீடு இயங்காது. return இல்லையென்றால், அல்லது மதிப்பு இல்லாமல் எழுதப்பட்டிருந்தால், செயல்பாடு None தரும்.

def area(w, h):
    w * h          # முடிவு கணக்கிடப்பட்டு வீணாகிறது

print(area(3, 4))  # None

def area(w, h):
    return w * h

print(area(3, 4))  # 12

மறந்துபோன return தொடக்கநிலையாளரின் மிகப் பொதுவான தவறுகளில் ஒன்று: செயல்பாடு "வேலை செய்கிறது", ஆனால் None தருகிறது, பிழை அடுத்த வரியில் வெளிப்படுகிறது. பல மதிப்புகளையும் திருப்பித் தரலாம் — உண்மையில் அது ஒரு tuple; அதை எளிதாகப் பிரிக்கலாம்:

def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([4, 1, 9])
print(low, high)   # 1 9

ஆரம்பத்திலேயே return தருவது தேவையற்ற உள்ளமைவைத் தவிர்க்க உதவும்: முதலில் சிறப்பு நிலைகளைத் தள்ளிவிட்டு, பிறகு முக்கிய தர்க்கத்தை எழுதுங்கள்.

def discount(price, is_member):
    if price <= 0:
        return 0
    if not is_member:
        return price
    return price * 0.9

Python செயல்பாட்டு வாதங்கள்: நிலை மற்றும் பெயரிட்டவை

அளவுருக்கள் என்பவை செயல்பாட்டு அறிவிப்பில் உள்ள பெயர்கள்; வாதங்கள் அழைக்கும்போது அனுப்பப்படும் மதிப்புகள். வாதங்களை வரிசைப்படி (நிலையாக) அல்லது பெயரால் (பெயரிட்டு) அனுப்பலாம். பெயரிட்ட வாதங்கள் அழைப்பை தானாக விளக்கமளிக்கும்படி ஆக்குகின்றன; வரிசை முக்கியமற்றதாகிறது.

def add_expense(title, amount, category="மற்றவை"):
    return {"title": title, "amount": amount, "category": category}

add_expense("காபி", 250)                          # நிலையாக
add_expense(amount=250, title="காபி")             # பெயரால்
add_expense("டாக்ஸி", 600, category="போக்குவரத்து")   # கலந்து

இயல்பு மதிப்புள்ள அளவுரு கட்டாயமற்றது. விதிகள்: இயல்பு மதிப்புள்ள அளவுருக்கள் கட்டாயமானவற்றுக்குப் பின் வர வேண்டும்; அழைக்கும்போது நிலை வாதங்கள் பெயரிட்ட வாதங்களுக்கு முன் வர வேண்டும். இல்லையென்றால் Python SyntaxError தரும்.

பொறி: மாற்றக்கூடிய இயல்பு மதிப்பு

இயல்பு மதிப்பு ஒரே ஒருமுறை கணக்கிடப்படுகிறது — def வரி இயங்கும்போது, ஒவ்வொரு அழைப்பின்போதும் அல்ல. அது பட்டியலோ அகராதியோ என்றால் அது எல்லா அழைப்புகளுக்கும் பொதுவாக இருக்கும்.

def add_item(item, acc=[]):
    acc.append(item)
    return acc

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] — பட்டியல் முந்தைய அழைப்பை "நினைவில்" வைத்திருக்கிறது

சரியான வழி — இயல்பாக None வைத்து உள்ளே புதிய பொருளை உருவாக்குவது:

def add_item(item, acc=None):
    if acc is None:
        acc = []
    acc.append(item)
    return acc

*args மற்றும் **kwargs: எத்தனை வாதங்களும்

அளவுருவுக்கு முன் உள்ள ஒரு நட்சத்திரக்குறி கூடுதல் நிலை வாதங்களை tuple-ஆகவும், இரண்டு நட்சத்திரக்குறிகள் கூடுதல் பெயரிட்ட வாதங்களை அகராதியாகவும் (dict) சேகரிக்கும். args மற்றும் kwargs பெயர்கள் ஒரு மரபு மட்டுமே; முக்கியம் நட்சத்திரக்குறிகள்.

def total(*args):
    return sum(args)

print(total(100, 250, 40))   # 390

def make_user(name, **kwargs):
    user = {"name": name}
    user.update(kwargs)
    return user

print(make_user("அன்னா", city="சென்னை", age=30))
# {'name': 'அன்னா', 'city': 'சென்னை', 'age': 30}

அதே நட்சத்திரக்குறிகள் எதிர்த்திசையிலும் வேலை செய்யும் — அழைக்கும்போது அவை வரிசையையோ அகராதியையோ வாதங்களாக விரிக்கும்:

values = [3, 4]
print(pow(*values))          # 81

opts = {"sep": " | ", "end": "\n"}
print("a", "b", **opts)      # a | b

நிலை மட்டும் மற்றும் பெயர் மட்டும் அளவுருக்கள்

அளவுரு பட்டியலில் உள்ள சாய்வுக்கோடு / மற்றும் நட்சத்திரக்குறி * தடைகளைப் போல வேலை செய்கின்றன: /-க்கு முன் உள்ளவை வரிசைப்படி மட்டுமே அனுப்பப்படும் (தொடரியல் Python 3.8-இல் வந்தது, PEP 570); *-க்குப் பின் உள்ளவை பெயரால் மட்டுமே.

def convert(amount, /, *, rate, currency="USD"):
    return round(amount / rate, 2), currency

convert(100, rate=90.5)          # (1.1, 'USD')
convert(amount=100, rate=90.5)   # TypeError: amount நிலையாக மட்டுமே அனுப்பப்படும்
convert(100, 90.5)               # TypeError: rate — பெயரால் மட்டுமே

பெயர் மட்டும் அளவுருக்கள் convert(100, 90.5, "EUR") போன்ற அழைப்புகளிலுள்ள குழப்பத்தைத் தடுக்கின்றன — எது எது என்று தெளிவில்லாத அழைப்புகளை.

நோக்கப் பரப்பு (scope): LEGB விதி

Python ஒரு மாறியின் பெயரை இந்தச் சங்கிலியில் தேடும்: Local (செயல்பாட்டுக்குள்) → Enclosing (வெளிப்புறச் செயல்பாட்டில்) → Global (தொகுதி மட்டத்தில்) → Built-in (len போன்ற உள்ளமைவுப் பெயர்கள்). செயல்பாட்டுக்குள் உலகளாவிய மாறியைப் படிக்கலாம்; ஆனால் அதற்கு புதிய மதிப்பை ஒதுக்க global அறிவிப்பு வேண்டும்.

limit = 1000

def check(amount):
    return amount > limit    # உலகளாவிய மாறியைப் படித்தல் — சரி

def raise_limit():
    global limit
    limit = 2000             # global இல்லாமல் உள்ளூர் மாறி உருவாகியிருக்கும்

நடைமுறையில் global-ஐத் தவிர்ப்பது நல்லது: வெளிப்புற நிலையை மாற்றும் செயல்பாட்டைச் சோதிப்பது கடினம். மதிப்பை வாதமாகப் பெற்று முடிவைத் திருப்பித் தருவது நம்பகமானது.

உள்ளமை செயல்பாடுகளும் மூடல்களும் (closures)

ஒரு செயல்பாட்டுக்குள் இன்னொன்றை அறிவிக்கலாம். உள்ளமை செயல்பாடு வெளிப்புறச் செயல்பாடு முடிந்த பின்னும் அதன் மாறிகளைப் பார்க்கும் — இதுவே மூடல் (closure). அத்தகைய மாறியை மாற்ற nonlocal பயன்படுகிறது.

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

c = make_counter()
print(c(), c(), c())   # 1 2 3

மூடல்கள் அலங்கரிப்பாளர்களுக்கும் (decorators) செயல்பாட்டுத் தொழிற்சாலைகளுக்கும் அடிப்படை.

செயல்பாடும் ஒரு பொருளே

Python-இல் செயல்பாடு ஒரு சாதாரணப் பொருள்: அதை ஒரு மாறியில் வைக்கலாம், மற்றொரு செயல்பாட்டுக்கு அனுப்பலாம், ஒரு செயல்பாட்டிலிருந்து திருப்பித் தரலாம், அகராதியில் சேமிக்கலாம். அதற்கு பண்புக்கூறுகள் உண்டு: __name__, __doc__, __defaults__, __annotations__.

def double(x):
    return x * 2

f = double
print(f(5), f.__name__)                # 10 double
print(list(map(double, [1, 2, 3])))   # [2, 4, 6]

Python lambda: பெயரில்லாத செயல்பாடுகள்

Lambda செயல்பாடு பெயரில்லாத குறுகிய செயல்பாடு; அதன் உடல் ஒரே வெளிப்பாடு. வெளிப்பாட்டின் முடிவு தானாகத் திருப்பித் தரப்படும்; return எழுதக்கூடாது.

square = lambda x: x ** 2
print(square(4))   # 16

expenses = [("காபி", 250), ("டாக்ஸி", 600), ("மதிய உணவு", 450)]
expenses.sort(key=lambda e: e[1], reverse=True)
print(expenses)  # [('டாக்ஸி', 600), ('மதிய உணவு', 450), ('காபி', 250)]

print(list(filter(lambda n: n % 2 == 0, range(10))))  # [0, 2, 4, 6, 8]

Lambda செயல்பாடுகள் sorted, max, map, filter போன்றவற்றுக்கு குறுகிய வாதமாக பொருந்தும். மேலே square போல lambda-வை ஒரு மாறிக்கு ஒதுக்குவதை PEP 8 பரிந்துரைப்பதில்லை: செயல்பாட்டுக்குப் பெயர் வேண்டுமென்றால் def எழுதுங்கள் — அப்போது traceback-இல் சரியான __name__ இருக்கும், docstring-க்கும் இடம் கிடைக்கும்.

deflambda
பெயர்உண்டுஇல்லை (<lambda>)
உடல்எத்தனை கட்டளைகளும்ஒரே வெளிப்பாடு
returnவெளிப்படையானதுமறைமுகமானது
Docstring, annotationsஉண்டுஇல்லை
எங்கே பொருந்தும்எல்லா இடங்களிலும்குறுகிய key அல்லது callback

வகை குறிப்புகள் (annotations): குறிப்புகள், சோதனைகள் அல்ல

Annotations அளவுருக்களின் மற்றும் முடிவின் எதிர்பார்க்கப்படும் வகைகளை விவரிக்கின்றன. Python இயக்கும்போது அவற்றைச் சரிபார்ப்பதில்லை: x: int கொண்ட செயல்பாடு சரத்தையும் அமைதியாக ஏற்கும். அவற்றைச் சரிபார்ப்பது வெளிப்புறக் கருவிகள் — mypy, pyright, ty — மற்றும் இயக்குவதற்கு முன்பே பிழையைக் காட்டும் எடிட்டர்.

def add_expense(title: str, amount: float, category: str = "மற்றவை") -> dict[str, object]:
    return {"title": title, "amount": amount, "category": category}

def area(w: float, h: float) -> float:
    w * h   # mypy: Missing return statement

நிறுவாமல் சரிபார்ப்பை uvx mypy . மூலம் இயக்கலாம். மேலே உள்ள எடுத்துக்காட்டு annotations-இன் பயனைக் காட்டுகிறது: -> float இருக்கும்போது மறந்த return-ஐ பகுப்பாய்வாளர் உடனே பிடிக்கும்.

Python 3.12 (PEP 695) முதல் பொதுவான (generic) செயல்பாடுகளை TypeVar இல்லாமல் எழுதலாம்: வகை அளவுரு சதுர அடைப்புக்குள் குறிக்கப்படும், வகைப் புனைப்பெயர் type சொல்லால் அறிவிக்கப்படும்.

def first[T](xs: list[T]) -> T:
    return xs[0]

type Money = int | float

Python 3.14-இல் (PEP 649) annotations சோம்பேறியாக (lazy) மாறின: அவை முதல் பயன்பாட்டின்போது கணக்கிடப்படுகின்றன; அதனால் கீழே அறிவிக்கப்பட்ட வகுப்பை மேற்கோள் குறிகள் இல்லாமலே குறிப்பிடலாம், from __future__ import annotations இனி தேவையில்லை.

"கொடுக்கப்படவில்லை" அல்லது "None கொடுக்கப்பட்டது": Python 3.15-இல் sentinel

இயல்பாக None வைத்தால் "வாதம் கொடுக்கப்படவில்லை" என்பதையும் "வேண்டுமென்றே None கொடுக்கப்பட்டது" என்பதையும் பிரித்துப் பார்க்க முடியாது. பல ஆண்டுகளாக இதை சொந்தக் காவல் மதிப்பால் தீர்த்தனர்:

_MISSING = object()

def get_rate(currency, default=_MISSING):
    rates = {"USD": 90.5}
    if currency in rates:
        return rates[currency]
    if default is _MISSING:
        raise KeyError(currency)
    return default

Python 3.15-இல் sentinel என்ற உள்ளமைவுச் செயல்பாடு வந்தது (PEP 661): MISSING = sentinel("MISSING") தனித்துவமான குறியை உருவாக்கும்; அதற்குப் புரியும்படியான repr உண்டு, நகலெடுத்தாலும் அதே பொருளாக இருக்கும், pickle மூலம் தொடராக்கலாம், float | MISSING போன்ற annotation-களுக்கும் பொருந்தும். பழைய பதிப்புகளில் object() முறை தொடர்ந்து வேலை செய்யும்.

செயல்பாடுகளில் பொதுவான தவறுகள்

  • return மறந்தது — செயல்பாடு None தருகிறது.
  • அடைப்புக்குறிகள் மறந்தது — print(greet) அழைப்பின் முடிவைக் காட்டாமல் செயல்பாட்டுப் பொருளைக் காட்டும்.
  • மாற்றக்கூடிய இயல்பு மதிப்பு — எல்லா அழைப்புகளுக்கும் பொதுவான பட்டியல்.
  • தவறான எண்ணிக்கை வாதங்கள் — TypeError: greet() missing 1 required positional argument: 'name'.
  • உள்ளமைவுப் பெயருடன் மோதல் — list அல்லது sum என்ற செயல்பாடு உள்ளமைவைத் தடுக்கும்.

சுருக்கம்

Python-இல் செயல்பாடுகள் def-ஆல் அறிவிக்கப்படுகின்றன, return-ஆல் முடிவைத் திருப்பித் தருகின்றன, வாதங்களை வரிசைப்படியோ பெயராலோ ஏற்கின்றன. *args மற்றும் **kwargs நெகிழ்வைத் தரும், / மற்றும் * அழைப்பின் கடுமையைத் தரும், lambda ஒருமுறை பயன்படும் செயல்பாட்டுக்குச் சுருக்கத்தைத் தரும், வகை annotations mypy-உடன் சேர்ந்து பிழைகளை இயக்கத்துக்கு முன்பே பிடிக்கும். Python பாடநெறியில் இதை நடைமுறையில் கற்பிக்கிறோம்: செலவு கண்காணிப்பான் annotations-உடன் கூடிய செயல்பாடுகளாகப் பிரிக்கப்பட்டு mypy மூலம் சரிபார்க்கப்படுகிறது.

அடிக்கடி கேட்கப்படும் கேள்விகள்

அளவுருவுக்கும் வாதத்துக்கும் என்ன வேறுபாடு?

அளவுரு என்பது செயல்பாட்டு அறிவிப்பில் உள்ள பெயர்; வாதம் அழைக்கும்போது கொடுக்கப்படும் குறிப்பிட்ட மதிப்பு. <code>def greet(name)</code>-இல் name அளவுரு; <code>greet("அன்னா")</code>-இல் "அன்னா" என்ற சரம் வாதம்.

செயல்பாட்டை அறிவிப்பதற்கு முன் அழைக்க முடியுமா?

தொகுதி மட்டத்தில் முடியாது: அழைப்புக்கு முன் <code>def</code> வரி இயங்கியிருக்க வேண்டும், இல்லையென்றால் NameError வரும். ஆனால் மற்றொரு செயல்பாட்டுக்குள், அறிவிப்புக்குப் பின்னால் நடக்கும் அழைப்பு சரி.

ஒரு செயல்பாடு எத்தனை மதிப்புகளைத் திருப்பித் தர முடியும்?

முறையாக ஒன்று; ஆனால் அந்த ஒன்று tuple ஆக இருக்கலாம்: <code>return a, b</code> இரண்டு உறுப்புகளின் tuple-ஐத் தருகிறது; அதை <code>x, y = f()</code> என்று பிரிக்கலாம்.

வகை annotations கட்டாயமா?

இல்லை, அவை இல்லாமலும் Python வேலை செய்யும். ஆனால் மற்றவர்கள் படிக்கும் குறியீட்டில் அவை பராமரிப்பை எளிதாக்கும்; mypy அல்லது pyright இயக்குவதற்கு முன்பே பிழைகளைக் கண்டறியும்.

lambda-வில் if பயன்படுத்தலாமா?

நிபந்தனை வெளிப்பாடு மட்டும் பயன்படுத்தலாம்: <code>lambda x: "இரட்டை" if x % 2 == 0 else "ஒற்றை"</code>. lambda-வுக்குள் கட்டளைகள், சுழல்கள், ஒதுக்கல்கள் அனுமதிக்கப்படுவதில்லை.

இந்தத் தலைப்பை வீடியோவில் கற்றுக்கொள்ளுங்கள்

“Python 3.15: от новичка до профи” பாடநெறியில் இந்தத் தலைப்பு பயிற்சியுடன் விரிவாக விளக்கப்பட்டுள்ளது.

பாடநெறிக்குச் செல்