2012-11-23 9 views
7

Chciałbym zaimplementować opcjonalny program rejestrujący w funkcji. Coś takiego:Implementowanie opcjonalnego programu rejestrującego w kodzie

def foo(arg1, arg2, arg3, logger=None): 
    logger = logger or (lambda *x: None) 

    ... 
    self.logger.debug("The connection is lost.") 

Chcę, aby rejestracja się wydarzyła w przypadku, gdy istnieje rejestrator. W przeciwnym razie debugowanie rejestratora nic nie da.

Zasadniczo prostym sposobem na osiągnięcie tego jest zagnieżdżenie każdej instrukcji debugowania w bloku if logger, ale wydaje się nieporządne, gdy istnieje wiele instrukcji debugowania.

+0

Nie jestem pewien, jak to by działało w twojej sytuacji, ale czy mógłbyś poprowadzić funkcję sprawdzając, czy logger istnieje, a jeśli nie, stwórz rejestrator o tej samej nazwie ("logger", wydaje się) i kieruj wyjście do 'os.devnul'? – RocketDonkey

+0

@iTayb Cześć, masz dość prosty opis tego, co chcesz (żeby mieć fikcyjnego dziennikarza). ale logowanie Pythona zwykle nie jest używane w ten sposób, o ile wiem. Ponieważ możesz uzyskać filtrowanie rejestrowania, użyj nazwy rejestratora, czy mogę zapytać, dlaczego (w jakiej sytuacji) nadal potrzebujesz tego rodzaju obejścia? – tdihp

+0

@tdihp Chcę opracować kawałek kodu, który może rejestrować jego aktywność do dostarczonego rejestratora. Ten kod musi być przenośny. To (mam nadzieję) zostanie wdrożone w wielu różnych projektach i nie zapewniam środowiska logowania. Od dewelopera zależy, czy chce zarejestrować aktywność tej funkcji, czy nie. Po prostu daję mu opcję. – iTayb

Odpowiedz

7

kilka opcji:

Załóż obojętne logger (mój ulubiony):

logger = logger or logging.getLogger('dummy') # without configuring dummy before. 

Tworzenie fikcyjny obiekt z jednego poziomu null efekt:

class DummyObject(object): 
    def __getattr__(self, name): 
     return lambda *x: None 

logger = logger or DummyObject() 

zagnieżdżania każda instrukcja debugowania w bloku:

if logger: 
    logger.debug("abc") 
2

Do tego służy moduł logging. How to use, Cookbook.

Jeśli naprawdę chcesz się toczyć własnym, widzę kilka alternatyw:

  • self.logger atrybut. Ustawia podczas konstruowania obiektu lub dziedziczone z klasy bazowej. Każdy obiekt ma własny rejestrator, więc możesz mieć selektywne rejestrowanie dla każdej instancji.

  • Klasa rejestratora za pomocą metod statycznych lub modułu autonomicznego. Może mieć domyślne metody, które nic nie robią, ale użytkownik może je zastąpić prawdziwymi programami obsługi zawsze, gdy zajdzie taka potrzeba. Wszystkie klasy mają dostęp do tego samego obiektu lub modułu. Stracić ziarnistość, ale mniej pracy do skonfigurowania.

  • Decorators. Nad każdą metodą, która ma zostać zalogowana, umieść kod @log('message', LEVEL), który automatycznie wywoła dziennik po wywołaniu metody. Znacznie czystszy, mniej elastyczny.

+0

To jest dobre dla projektów. Wszystko, czego potrzebuję, to bardzo podstawowa funkcja, z opcjonalnym protokołowaniem, w którym rejestrator może zostać przekazany jako argument. – iTayb

+0

Dlaczego nie użyć opublikowanego kodu? Trzeba tylko stworzyć bardzo prostą klasę dla rejestratora, lub nawet funkcję drukowania tego, co zostało przekazane w parametrach. – BoppreH

+0

Zastanawiam się, czy istnieje obiekt w pythonie, który pozwoli na zapisywanie, nawet jeśli nie istnieje, i obsługuje podklasę (jak wywołanie klasy1.class2.func (a, b, c) i nic się nie stanie). – iTayb

1

myślę co chcesz loguje filtrowania więc moja odpowiedź jest po prostu o tym, jak osiągnąć filtrowanie rejestrowania.

Pakiet logowania Pythona już to robi, masz wiele sposobów na filtrowanie rejestrowania.

Dwa podstawowe sposoby to:

  • poziom rejestrowania filtrowanie
  • nazwa rejestratora filtrowanie

Obaj wykorzystuje config zalogowaniu, tak może być łatwo skonfigurowany.

Na przykład:

import logging 

logging.basicConfig() # easily setup a StreamHandler output 

logging.getLogger("realm1").setLevel(logging.WARNING) 
logging.getLogger("realm2").setLevel(logging.INFO) 

def test(): 
    r1logger = logging.getLogger("realm1") 
    r2logger = logging.getLogger("realm2") 
    r1logger.info('r1 info') # won't print 
    r2logger.info('r2 info') # will print 

if __name__ == '__main__': 
    test() 

Więc jeśli nie musi działać w czasie dynamicznych zmian lokalnych polityki rejestrowania, użycie domyślnego rejestrator starannego rejestrowania config byłoby wystarczające.

+0

Kto powiedział, że nie zamierzam używać poziomu logowania OSTRZEŻENIE? Ale mam twój pomysł. – iTayb

Powiązane problemy