ವಿಷಯಕ್ಕೆ ತೆರಳಿ

ಪೈಥಾನ್ ಡೆಕೋರೇಟರ್ಸ್: ಸಂದರ್ಶನ ಪ್ರಶ್ನೆಗಳು ಮತ್ತು ಉತ್ತರಗಳು

1. ಪೈಥಾನ್‌ನಲ್ಲಿ ಡೆಕೋರೇಟರ್ (Decorator) ಎಂದರೇನು?

ಉತ್ತರ: ಡೆಕೋರೇಟರ್ ಎನ್ನುವುದು ಒಂದು ವಿಶೇಷ ಫಂಕ್ಷನ್, ಅದು ಬೇರೊಂದು ಫಂಕ್ಷನ್‌ನ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸದೆ, ಅದರ ಕಾರ್ಯವನ್ನು ವಿಸ್ತರಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ. ಸರಳವಾಗಿ ಹೇಳುವುದಾದರೆ, ಇದು ಒಂದು ಫಂಕ್ಷನ್ ಅನ್ನು ಇನ್‌ಪುಟ್ ಆಗಿ ತೆಗೆದುಕೊಂಡು, ಅದಕ್ಕೆ ಹೊಸ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಸೇರಿಸಿ, ಹೊಸ ಫಂಕ್ಷನ್ ಅನ್ನು ಔಟ್‌ಪುಟ್ ಆಗಿ ನೀಡುತ್ತದೆ.

ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ @decorator_name ಸಿಂಟ್ಯಾಕ್ಸ್ ಬಳಸಿ ಅನ್ವಯಿಸಲಾಗುತ್ತದೆ.

ಉಪಯೋಗಗಳು:

  • ಲಾಗಿಂಗ್ (Logging)
  • ಕಾರ್ಯಕ್ಷಮತೆ ಪರೀಕ್ಷೆ (Performance testing)
  • ಪ್ರವೇಶ ನಿಯಂತ್ರಣ (Access control)
  • ಕ್ಯಾಶಿಂಗ್ (Caching)

2. ಪೈಥಾನ್‌ನಲ್ಲಿ ಫಂಕ್ಷನ್‌ಗಳು ಫಸ್ಟ್-ಕ್ಲಾಸ್ ಆಬ್ಜೆಕ್ಟ್ಸ್ (First-Class Objects) ಎಂದರೆ ಏನು?

ಉತ್ತರ: ಪೈಥಾನ್‌ನಲ್ಲಿ ಫಂಕ್ಷನ್‌ಗಳನ್ನು ಫಸ್ಟ್-ಕ್ಲಾಸ್ ಆಬ್ಜೆಕ್ಟ್ಸ್ ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ. ಇದರರ್ಥ:

  1. ಫಂಕ್ಷನ್‌ಗಳನ್ನು ವೇರಿಯೇಬಲ್‌ಗಳಿಗೆ ಅಸೈನ್ ಮಾಡಬಹುದು.
  2. ಫಂಕ್ಷನ್‌ಗಳನ್ನು ಬೇರೆ ಫಂಕ್ಷನ್‌ಗಳಿಗೆ ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ಕಳುಹಿಸಬಹುದು.
  3. ಫಂಕ್ಷನ್‌ಗಳು ಬೇರೆ ಫಂಕ್ಷನ್‌ಗಳನ್ನು ರಿಟರ್ನ್ ಮಾಡಬಹುದು.
  4. ಫಂಕ್ಷನ್‌ಗಳನ್ನು ಲಿಸ್ಟ್, ಡಿಕ್ಷನರಿ ಮುಂತಾದ ಡೇಟಾ ಸ್ಟ್ರಕ್ಚರ್‌ಗಳಲ್ಲಿ ಸ್ಟೋರ್ ಮಾಡಬಹುದು.

ಈ ಗುಣಲಕ್ಷಣವೇ ಡೆಕೋರೇಟರ್‌ಗಳ ಅಸ್ತಿತ್ವಕ್ಕೆ ಮೂಲ ಕಾರಣ.

3. ಒಂದು ಸರಳ ಡೆಕೋರೇಟರ್ ಅನ್ನು ಹೇಗೆ ರಚಿಸುವುದು?

ಉತ್ತರ: ಒಂದು ಡೆಕೋರೇಟರ್ ರಚಿಸಲು ಈ ಕೆಳಗಿನ ಹಂತಗಳನ್ನು ಅನುಸರಿಸಬೇಕು:

  1. ಒಂದು ಫಂಕ್ಷನ್ (ಡೆಕೋರೇಟರ್) ಡಿಫೈನ್ ಮಾಡಿ, ಅದು ಇನ್ನೊಂದು ಫಂಕ್ಷನ್ ಅನ್ನು ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ.
  2. ಈ ಡೆಕೋರೇಟರ್ ಫಂಕ್ಷನ್‌ನೊಳಗೆ, ಇನ್ನೊಂದು "ವ್ರ್ಯಾಪರ್" (wrapper) ಫಂಕ್ಷನ್ ಅನ್ನು ಡಿಫೈನ್ ಮಾಡಿ.
  3. ವ್ರ್ಯಾಪರ್ ಫಂಕ್ಷನ್‌ನೊಳಗೆ, ಮೂಲ ಫಂಕ್ಷನ್‌ಗೆ ಬೇಕಾದ ಹೆಚ್ಚುವರಿ ಕಾರ್ಯವನ್ನು ಸೇರಿಸಿ ಮತ್ತು ಮೂಲ ಫಂಕ್ಷನ್ ಅನ್ನು ಕಾಲ್ ಮಾಡಿ.
  4. ಡೆಕೋರೇಟರ್ ಫಂಕ್ಷನ್‌ನಿಂದ ವ್ರ್ಯಾಪರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ರಿಟರ್ನ್ ಮಾಡಿ.

ಉದಾಹರಣೆ:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")

    return wrapper


@my_decorator
def say_hello():
    print("Hello!")


say_hello()

ಔಟ್‌ಪುಟ್:

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

4. ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಹೊಂದಿರುವ ಫಂಕ್ಷನ್‌ಗೆ ಡೆಕೋರೇಟರ್ ಅನ್ನು ಹೇಗೆ ಬಳಸುವುದು?

ಉತ್ತರ: ಮೂಲ ಫಂಕ್ಷನ್ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಹೊಂದಿದ್ದರೆ, ವ್ರ್ಯಾಪರ್ ಫಂಕ್ಷನ್ ಕೂಡ ಅದೇ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಬೇಕು. ಇದನ್ನು *args ಮತ್ತು **kwargs ಬಳಸಿ ಸುಲಭವಾಗಿ ಮಾಡಬಹುದು. ಇದು ಡೆಕೋರೇಟರ್ ಅನ್ನು ಯಾವುದೇ ರೀತಿಯ ಫಂಕ್ಷನ್‌ಗೆ ಅನ್ವಯಿಸಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.

ಉದಾಹರಣೆ:

def smart_divide_decorator(func):
    def wrapper(a, b):
        if b == 0:
            return "Cannot divide by zero."
        return func(a, b)

    return wrapper


@smart_divide_decorator
def divide(a, b):
    return a / b


print(divide(10, 2))  # 5.0
print(divide(10, 0))  # Cannot divide by zero.

5. functools.wraps ಡೆಕೋರೇಟರ್‌ನ ಉಪಯೋಗವೇನು?

ಉತ್ತರ: ಡೆಕೋರೇಟರ್ ಬಳಸಿದಾಗ, ಮೂಲ ಫಂಕ್ಷನ್‌ನ ಮೆಟಾಡೇಟಾ (ಹೆಸರು, ಡಾಕ್‌ಸ್ಟ್ರಿಂಗ್ ಇತ್ಯಾದಿ) ಕಳೆದುಹೋಗುತ್ತದೆ ಮತ್ತು ವ್ರ್ಯಾಪರ್ ಫಂಕ್ಷನ್‌ನ ಮೆಟಾಡೇಟಾ ಬರುತ್ತದೆ.

@functools.wraps ಡೆಕೋರೇಟರ್ ಅನ್ನು ವ್ರ್ಯಾಪರ್ ಫಂಕ್ಷನ್‌ಗೆ ಅನ್ವಯಿಸುವುದರಿಂದ, ಮೂಲ ಫಂಕ್ಷನ್‌ನ ಹೆಸರು (__name__), ಡಾಕ್‌ಸ್ಟ್ರಿಂಗ್ (__doc__), ಮತ್ತು ಇತರ ಮೆಟಾಡೇಟಾವನ್ನು ಸಂರಕ್ಷಿಸಲಾಗುತ್ತದೆ. ಇದು ಡೀಬಗ್ಗಿಂಗ್ ಮಾಡಲು ಬಹಳ ಸಹಾಯಕ.

ಉದಾಹರಣೆ:

import functools


def my_decorator(func):
    @functools.wraps(func)  # ಮೂಲ ಫಂಕ್ಷನ್‌ನ ಮೆಟಾಡೇಟಾವನ್ನು ಕಾಪಿ ಮಾಡುತ್ತದೆ
    def wrapper(*args, **kwargs):
        # ...
        return func(*args, **kwargs)

    return wrapper


@my_decorator
def my_function():
    """This is my function's docstring."""
    pass


print(my_function.__name__)  # 'my_function' (wraps ಇಲ್ಲದಿದ್ದರೆ 'wrapper' ಇರುತ್ತಿತ್ತು)
print(my_function.__doc__)  # 'This is my function's docstring.'