2011-08-18 30 views
9

tôi đã đưa ra đoạn mã sau để trang trí các phương pháp dụ sử dụng một trang trí đòi hỏi thể hiện chính nó như là một cuộc tranh cãi:Python: Bất cứ điều gì sai trái với tự động gán các phương pháp dụ như dụ thuộc tính

from functools import wraps 

def logging_decorator(tricky_instance): 
    def wrapper(fn): 
     @wraps(fn) 
     def wrapped(*a, **kw): 
      if tricky_instance.log: 
       print("Calling %s.." % fn.__name__) 
      return fn(*a, **kw) 
     return wrapped 
    return wrapper  

class Tricky(object): 
    def __init__(self, log): 
     self.log = log 
     self.say_hi = logging_decorator(self)(self.say_hi) 

    def say_hi(self): 
     print("Hello, world!") 


i1 = Tricky(log=True) 
i2 = Tricky(log=False) 

i1.say_hi() 
i2.say_hi() 

Điều này dường như công việc tuyệt vời , nhưng tôi sợ rằng tôi có thể đã bỏ qua một số tác dụng phụ không mong muốn của thủ thuật này. Tôi có muốn tự bắn mình vào chân hay điều này an toàn không?

Lưu ý rằng tôi không thực sự muốn sử dụng tính năng này để ghi nhật ký, đó chỉ là ví dụ ngắn nhất có ý nghĩa mà tôi có thể đưa ra.

+0

Dường như hợp pháp. Imho. – Evpok

Trả lời

2

Tôi nghĩ rằng tôi đang cố gắng không cần thiết thông minh. Dường như có một giải pháp đơn giản hơn đáng xấu hổ:

from functools import wraps 

def logging_decorator(fn): 
    @wraps(fn) 
    def wrapped(self, *a, **kw): 
     if self.log: 
      print("Calling %s.." % fn.__name__) 
     return fn(self, *a, **kw) 
    return wrapped 

class Tricky(object): 
    def __init__(self, log): 
     self.log = log 

    @logging_decorator 
    def say_hi(self): 
     print("Hello, world!") 

i1 = Tricky(log=True) 
i2 = Tricky(log=False) 

i1.say_hi() 
i2.say_hi() 
4

Nó không thực sự rõ ràng với tôi tại sao bạn sẽ muốn làm điều này. Nếu bạn muốn gán một loại phương pháp mới sử dụng động types:

import types 

class Tricky(object): 
    def __init__(self): 
     def method(self): 
      print('Hello') 
     self.method = types.MethodType(method, self) 

Nếu bạn muốn làm điều gì đó với các ví dụ, làm điều đó trong phương pháp __init__. Nếu bạn chỉ muốn truy cập vào dụ của phương pháp bên trong trang trí, bạn có thể sử dụng im_self thuộc tính:

def decorator(tricky_instance): 
    def wrapper(meth): 
     print(meth.im_self == tricky_instance) 
     return meth 
    return wrapper 

Cá nhân, tôi nghĩ rằng đây là chuyển hướng sang đất Có lẽ-I-Shouldn't-Sử dụng-trang trí.

+0

Tôi muốn tự động gọi lại các phương thức thể hiện trên các vấn đề mạng (tạm thời), được chỉ ra bởi các ngoại lệ. Ngoại lệ nào là tạm thời và vĩnh viễn phụ thuộc vào cá thể thực tế (các cá thể đại diện cho các đối tượng Amazon S3 có sự nhất quán đảm bảo phụ thuộc vào vị trí lưu trữ). – Nikratio

+0

Tôi không hiểu mã của bạn làm gì/tốt. Bạn có thể xây dựng? – Nikratio

+1

Mã của tôi tạo một phương thức thể hiện mới trong '__init__'. Tôi đoán bạn đang cố gắng để viết một trang trí, và bạn muốn trang trí có quyền truy cập vào ví dụ của phương pháp được trang trí, để khái quát hoá trang trí? – zeekay

Các vấn đề liên quan