Python Functions: Định nghĩa và Sử dụng

Học cách viết functions trong Python - parameters, return values, *args, **kwargs, decorators.

Functions là gì?

Functions là các khối code có thể tái sử dụng, giúp tổ chức và modularize chương trình.

Định nghĩa Function

# Cú pháp cơ bản
def greet():
    print("Hello, World!")

# Gọi function
greet()  # Hello, World!

# Function với docstring
def scan_port():
    """
    Scan a single port.
    Returns True if port is open.
    """
    pass

Parameters và Arguments

# Positional parameters
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")  # Hello, Alice!

# Multiple parameters
def scan_port(host, port):
    print(f"Scanning {host}:{port}")

scan_port("192.168.1.1", 80)

# Default parameters
def scan_port(host, port=80, timeout=1.0):
    print(f"Scanning {host}:{port} (timeout: {timeout}s)")

scan_port("192.168.1.1")          # port=80, timeout=1.0
scan_port("192.168.1.1", 443)     # port=443, timeout=1.0
scan_port("192.168.1.1", timeout=2.0)  # Keyword argument

Return Values

# Single return value
def add(a, b):
    return a + b

result = add(5, 3)  # 8

# Multiple return values (tuple)
def get_server_info():
    return "192.168.1.1", 443, "HTTPS"

ip, port, protocol = get_server_info()

# Early return
def is_valid_port(port):
    if port < 1 or port > 65535:
        return False
    return True

*args và **kwargs

# *args - variable positional arguments
def scan_ports(host, *ports):
    for port in ports:
        print(f"Scanning {host}:{port}")

scan_ports("192.168.1.1", 22, 80, 443, 3306)

# **kwargs - variable keyword arguments
def create_request(url, **options):
    print(f"URL: {url}")
    for key, value in options.items():
        print(f"  {key}: {value}")

create_request(
    "https://api.example.com",
    method="POST",
    timeout=30,
    headers={"Auth": "Bearer token"}
)

# Kết hợp
def api_call(endpoint, *args, **kwargs):
    print(f"Endpoint: {endpoint}")
    print(f"Args: {args}")
    print(f"Kwargs: {kwargs}")

Type Hints

from typing import List, Dict, Optional, Tuple

def scan_port(host: str, port: int, timeout: float = 1.0) -> bool:
    """
    Scan a single port on host.
    
    Args:
        host: Target hostname or IP
        port: Port number to scan
        timeout: Connection timeout in seconds
    
    Returns:
        True if port is open, False otherwise
    """
    # Implementation
    return True

def get_open_ports(host: str, ports: List[int]) -> List[int]:
    """Return list of open ports."""
    open_ports = []
    for port in ports:
        if scan_port(host, port):
            open_ports.append(port)
    return open_ports

def find_service(port: int) -> Optional[str]:
    """Return service name or None if not found."""
    services = {22: "SSH", 80: "HTTP", 443: "HTTPS"}
    return services.get(port)

Lambda Functions

# Anonymous functions
square = lambda x: x ** 2
print(square(5))  # 25

# Với sorted()
servers = [
    {"name": "web1", "load": 85},
    {"name": "web2", "load": 45},
    {"name": "web3", "load": 70}
]

# Sắp xếp theo load
sorted_servers = sorted(servers, key=lambda s: s["load"])

# Với filter()
ports = [22, 80, 443, 8080, 3306]
secure_ports = list(filter(lambda p: p in [443, 22], ports))
# [22, 443]

# Với map()
doubled = list(map(lambda x: x * 2, [1, 2, 3]))
# [2, 4, 6]

Scope và Closures

# Global vs Local scope
global_var = "I'm global"

def outer():
    outer_var = "I'm outer"
    
    def inner():
        inner_var = "I'm inner"
        print(global_var)   # Accessible
        print(outer_var)    # Accessible
        print(inner_var)    # Accessible
    
    inner()

# Closure - function nhớ scope của nó
def create_scanner(host):
    def scan(port):
        print(f"Scanning {host}:{port}")
    return scan

scanner = create_scanner("192.168.1.1")
scanner(80)   # Scanning 192.168.1.1:80
scanner(443)  # Scanning 192.168.1.1:443

Decorators

import time
from functools import wraps

# Basic decorator
def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    return "Done"

slow_function()  # slow_function took 1.00s

# Decorator with arguments
def retry(times=3):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(times):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"Attempt {attempt + 1} failed: {e}")
            raise Exception(f"Failed after {times} attempts")
        return wrapper
    return decorator

@retry(times=3)
def flaky_request():
    # Might fail sometimes
    pass

Ứng dụng: Port Scanner Function

import socket
from typing import List, Tuple
from concurrent.futures import ThreadPoolExecutor

def scan_single_port(host: str, port: int, timeout: float = 1.0) -> Tuple[int, bool]:
    """Scan a single port."""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    try:
        result = sock.connect_ex((host, port))
        return (port, result == 0)
    finally:
        sock.close()

def scan_ports(
    host: str, 
    ports: List[int], 
    threads: int = 100
) -> List[int]:
    """Scan multiple ports with threading."""
    open_ports = []
    
    with ThreadPoolExecutor(max_workers=threads) as executor:
        futures = [
            executor.submit(scan_single_port, host, port) 
            for port in ports
        ]
        
        for future in futures:
            port, is_open = future.result()
            if is_open:
                open_ports.append(port)
    
    return sorted(open_ports)

# Usage
if __name__ == "__main__":
    target = "scanme.nmap.org"
    ports = list(range(1, 1025))
    
    open_ports = scan_ports(target, ports)
    print(f"Open ports: {open_ports}")

Bước tiếp theo

Trong bài tiếp theo:

  • File I/O: Đọc và ghi files
  • Exception Handling: Try/except
  • Context Managers: with statement

💡 Pro tip: Một function nên làm một việc duy nhất. Nếu function quá dài, hãy chia nhỏ!