2013-06-12 28 views
7

tôi đang cố gắng để thực hiện phiên bản riêng của tôi về một DailyLogFilePython: tại sao một phương pháp từ siêu lớp không nhìn thấy?

from twisted.python.logfile import DailyLogFile 

class NDailyLogFile(DailyLogFile): 

    def __init__(self, name, directory, rotateAfterN = 1, defaultMode=None): 
     DailyLogFile.__init__(self, name, directory, defaultMode) # why do not use super. here? lisibility maybe? 
     # 
     self.rotateAfterN = rotateAfterN 

    def shouldRotate(self): 
     """Rotate when N days have passed since file creation""" 
     delta = datetime.date(*self.toDate()) - datetime.date(*self.toDate(self.createdOn)) 
     return delta > datetime.timedelta(self.rotateAfterN) 

    def __getstate__(self): 
     state = BaseLogFile.__getstate__(self) 
     del state["rotateAfterN"] 
     return state 

threadable.synchronize(NDailyLogFile) 

nhưng có vẻ như tôi bỏ lỡ một cơ bản của quá trình subclassing Python ... như tôi nhận được lỗi này:

Traceback (most recent call last): 
    File "/home/twistedtestproxy04.py", line 88, in <module> 
    import ndailylogfile 
    File "/home/ndailylogfile.py", line 56, in <module> 
    threadable.synchronize(NDailyLogFile) 
    File "/home/lt/mpv0/lib/python2.6/site-packages/twisted/python/threadable.py", line 71, in synchronize 
    sync = _sync(klass, klass.__dict__[methodName]) 
KeyError: 'write' 

vì vậy tôi cần thêm rõ ràng và xác định các phương thức khác như phương pháp Writerotate như sau:

class NDailyLogFile(DailyLogFile): 
    [...] 
    def write(self, data): # why must i add these ? 
     DailyLogFile.write(self, data) 

    def rotate(self): # as we do nothing more than calling the method from the base class! 
      DailyLogFile.rotate(self) 

threadable.synchronize(NDailyLogFile) 

whi le tôi nghĩ rằng nó sẽ được thừa hưởng chính xác từ lớp mẹ cơ sở. Lưu ý rằng tôi không làm gì cả, chỉ gọi "siêu",

xin vui lòng ai đó có thể giải thích tại sao tôi sai về ý tưởng đầu tiên của tôi rằng không nhất thiết phải thêm phương thức Viết?

có cách nào để nói với Python bên trong NDailyLogFile của tôi rằng nó shoud có tất cả các phương thức DailyLogFile không được xác định trực tiếp từ lớp mẹ của nó? Vì vậy, nó ngăn cản vua này lỗi _sync(klass, klass.__dict__[methodName] và tránh để chỉ định excplicitly?

(mã gốc của DailyLogFile rằng cảm hứng cho tôi nó lấy từ nguồn xoắn đây https://github.com/tzuryby/freespeech/blob/master/twisted/python/logfile.py)

EDIT: về việc sử dụng super, tôi nhận được:

File "/home/lt/inwork/ndailylogfile.py", line 57, in write 
    super.write(self, data) 
exceptions.AttributeError: type object 'super' has no attribute 'write' 

như vậy sẽ không sử dụng nó. Mặc dù tôi đã đúng ... tôi chắc chắn đã bỏ lỡ điều gì đó

+1

Từ quan điểm OOP bạn đang làm đúng, ngoại trừ bạn không thực sự muốn ghi đè tất cả các phương thức. Và bạn thực sự nên sử dụng 'super'. Vấn đề là 'threadable.py' không phải là rất thân thiện với các công cụ OOP, như là dòng mà ném một lỗi kiểm tra sự tồn tại của' viết' trong * mà lớp cụ thể *, nhưng không phải là tổ tiên. Tôi không có kinh nghiệm với 'xoắn' nên không biết cách vượt qua điều này. Có lẽ có một số hướng dẫn về một nơi nào đó trên internet? – J0HN

+0

ok, cảm ơn bạn đã bình luận. Tôi không biết nếu có một câu trả lời tốt hơn cho bây giờ. nhưng bạn đã cung cấp một phần tốt :) – user2468222

+0

Tôi nghĩ rằng cách ngớ ngẩn và có lẽ sai lầm để đạt được những gì bạn đang cố gắng làm là để thay thế 'klass .__ dict __ [methodName]' với 'getattr (klass, methodname)' trong 'threadable .py'. Và rất có thể nó sẽ không hoạt động. Và đó là một miếng vá để xoắn. Và nó có thể phá vỡ một cái gì đó bên ngoài trường hợp sử dụng cụ thể đó. Vì vậy, hãy thử nó như là một bằng chứng của khái niệm và nếu nó thực sự hoạt động - đề nghị như một bản vá để xoắn thông qua danh sách ốm yếu hoặc theo dõi vé hoặc bất cứ điều gì họ sử dụng để thúc đẩy phát triển. Và đừng quên đăng một cái gì đó ở đây vì vậy tôi sẽ biết nếu nó đã giúp :) – J0HN

Trả lời

2

Tôi dám nói rằng mã twisted/python/threadable.py có lỗi trong đó. __dict__ chỉ trả về thuộc tính cục bộ, không trả về thuộc tính được kế thừa. Otherposts nói sử dụng dir() hoặc inspect.getmembers() để tải xuống.

Tin tốt là bạn đúng với ý tưởng đầu tiên của mình rằng phương pháp write được kế thừa. Tin xấu là Twisted không nhận ra các phương pháp kế thừa, vì vậy bạn phải tự viết chúng.

+0

'dir' sẽ trả về một danh sách các thuộc tính và phương thức công cụ, nhưng không trả về các phương thức. 'inspect.getmembers' trả về một danh sách các bộ cấu trúc (' name', 'value'), vì vậy có thể tìm ra một phương thức, nhưng khó hơn là chỉ sử dụng' getattr'. – J0HN

+0

vì vậy tôi có thể thêm chúng một cách rõ ràng từ lớp con mà không cần phải xác định chúng? tôi không chắc chắn để có được điểm ở đây về cách tôi có thể sử dụng 'dir' hoặc' inspect.getmembers() 'cho việc này. – user2468222

+0

@ user2468222 bạn sẽ phải vá 'threadable.py', nhưng thực hiện nó theo cách liên quan hơn là sử dụng' getattr' – J0HN

3

Có một workaround, chỉ cần làm:

NDailyLogFile.__dict__ = dict(NDailyLogFile.__dict__.items() + DailyLogFile.__dict__.items()) 
threadable.synchronize(NDailyLogFile) 

Có một vấn đề ở đây mà bạn đang sử dụng các lớp mà không cần phải khởi tạo nó. Cách giải quyết này hoạt động vì bạn buộc phải thay đổi các thuộc tính lớp trước khi diễn giải.

Một chú thích quan trọng khác cho lớp con DailyLogFile lệnh super sẽ không hoạt động, vì DailyLogFile là một "lớp kiểu cũ" hoặc "classobj". super chỉ hoạt động cho các lớp "kiểu mới". See this question for further information about this.

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