Python 코드에 대해 log를 호출하는 함수 및 메서드를 자동으로 추가하는 세 가지 방법
이전 방식, 수동 로깅
import logging
logger = logging.getLogger(__name__)
def func(*args, **kwargs):
logger.info(f'Call func with {args, kwargs}')
func(1, 2, 3, a=True, b='arg')
INFO:__main__:Call func with ((1, 2, 3), {'a': True, 'b': 'arg'})
1. 데코레이터 사용
기능을 위해
def func_logger(func):
def inner(*args, **kwargs):
ret = func(*args, **kwargs)
logger.info(f'Call func {func.__name__} with {args, kwargs} returns {ret}')
return ret
return inner
@func_logger
def add(a, b):
return a + b
add(1,2)
add(1, b=2)
add(a=1, b=2)
INFO:__main__:Call func add with ((1, 2), {}) returns 3
INFO:__main__:Call func add with ((1,), {'b': 2}) returns 3
INFO:__main__:Call func add with ((), {'a': 1, 'b': 2}) returns 3
방법의 경우
self
보살핌이 필요합니다.def method_logger(method):
def inner(self, *args, **kwargs):
ret = method(self, *args, **kwargs)
logger.info(f'Call method {method.__name__} of {self} with {args, kwargs} returns {ret}')
return ret
return inner
class A:
a:int
def __init__(self, a):
self.a = a
@method_logger
def addX(self, x: int):
return self.a + x
def __repr__(self):
return f'A(a={self.a})'
a = A(1)
a.addX(2)
a.addX(x=3)
INFO:__main__:Call method addX of A(a=1) with ((2,), {}) returns 3
INFO:__main__:Call method addX of A(a=1) with ((), {'x': 3}) returns 4
로그의 개체를 설명하려면 클래스에 대해 사용자 지정
__str__
또는 __repr__
메서드를 정의하는 것이 좋습니다. 한 가지 간단한 방법은 dataclass
를 사용하는 것입니다.from dataclasses import dataclass
@dataclass
class Account:
uid: str
banlance: int
@method_logger
def transerTo(self, target: 'Account', value:int):
self.banlance -= value
target.banlance += value
return self, target
a = Account('aaaa', 10)
b = Account('bbbb', 10)
a.transerTo(b, 5)
INFO:__main__:Call method transerTo of Account(uid='aaaa', banlance=5) with ((Account(uid='bbbb', banlance=15), 5), {}) returns (Account(uid='aaaa', banlance=5), Account(uid='bbbb', banlance=15))
2. __getattribute__ 메소드 사용
def method_logger_x(method, obj):
def inner(*args, **kwargs):
ret = method(*args, **kwargs)
logger.info(f'Call method {method.__name__} of {obj} with {args, kwargs} returns {ret}')
return ret
return inner
class MethodLogger:
def __getattribute__(self, key):
value = super().__getattribute__(key)
if callable(value) and not key.startswith('__'):
return method_logger_x(value, self)
return value
@dataclass
class Account(MethodLogger):
uid: str
banlance: int
frozen: bool = False
def transerTo(self, target: 'Account', value:int):
self.banlance -= value
target.banlance += value
return self, target
def freeze(self, reason:str):
self.frozen = True
a = Account('aaaa', 10)
b = Account('bbbb', 10)
a.transerTo(b, 5)
a.freeze('Dangerous Action')
INFO:__main__:Call method transerTo of Account(uid='aaaa', banlance=5, frozen=False) with ((Account(uid='bbbb', banlance=15, frozen=False), 5), {}) returns (Account(uid='aaaa', banlance=5, frozen=False), Account(uid='bbbb', banlance=15, frozen=False))
INFO:__main__:Call method freeze of Account(uid='aaaa', banlance=5, frozen=True) with (('Dangerous Action',), {}) returns None
PS 개체의 메서드
__getattribute__
를 호출할 때 값(메서드)은 이미 self
매개변수를 얻었습니다.3. 메타 클래스 사용
def method_logger(method):
def inner(self, *args, **kwargs):
ret = method(self, *args, **kwargs)
logger.info(f'Call method {method.__name__} of {self} with {args, kwargs} returns {ret}')
return ret
return inner
from typing import Tuple
class MethodLoggerMeta(type):
def __new__(self, name:str, bases:Tuple[type], attrs:dict):
attrs_copy = attrs.copy()
for key, value in attrs.items():
if callable(value) and not key.startswith('__'):
attrs_copy[key] = method_logger(value)
return type(name, bases, attrs_copy)
@dataclass
class Account(metaclass=MethodLoggerMeta):
uid: str
banlance: int
frozen: bool = False
def transerTo(self, target: 'Account', value:int):
self.banlance -= value
target.banlance += value
return self, target
def freeze(self, reason:str):
self.frozen = True
a = Account('aaaa', 10)
b = Account('bbbb', 10)
a.transerTo(b, 5)
결론
더 많은 로그를 추가하는 것이 더 나은 방법입니다. 세 가지 방법 중 원하는 방법을 선택할 수 있습니다.
Reference
이 문제에 관하여(Python 코드에 대해 log를 호출하는 함수 및 메서드를 자동으로 추가하는 세 가지 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/duyixian1234/three-ways-to-automatically-add-functions-and-methods-calling-log-for-python-code-5fd0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)