darts.util.events là một thư viện Python cung cấp một dispatcher sự kiện đơn giản, tương tự như các cấu kiện được cung cấp bởi các ngôn ngữ C #. & Nbsp; Các thư viện không có người phụ thuộc bên ngoài.
Nó được dự định cho các trường hợp sử dụng, nơi các thành phần phát các sự kiện và các thành phần nghe cho các sự kiện đồng ý về các loại sự kiện và ngữ nghĩa liên kết với nó. Điều này đúng, ví dụ, để xử lý sự kiện, mà lắng nghe trên "click" sự kiện báo hiệu bởi các đối tượng nút GUI, hoặc các thông báo báo hiệu bởi các đối tượng, bất cứ khi nào giá trị của một số thay đổi sở hữu. Điều này khác với các phương pháp của, nói, PyDispatcher, đó là chung chung hơn, và ủng hộ giao tiếp giữa các thành phần yếu ớt cùng.
Compatibility
Mã này đã được viết cho và thử nghiệm với Python 2.6. Nó cần được tương thích với 2.5 là tốt, nhưng bạn có thể có để chèn một vài từ __future__ nhập khẩu dòng with_statement ở đây và ở đó. Nó sẽ làm việc (điều này chưa được thử nghiệm) với triển khai thay thế của Python như Jython hoặc IronPython. Lưu ý, mặc dù, rằng một số các trường hợp thử nghiệm được xác định trong tập tin này có thể thất bại do việc triển khai thu gom rác thải khác nhau; tập tin này được viết với CPython trong tâm trí.
Tài liệu
Cách sử dụng cơ bản
& Nbsp; >>> từ darts.lib.utils.event Nhà xuất bản nhập khẩu, ReferenceRetention như RR
& Nbsp; >>> some_event = Nhà xuất bản ()
Nhà xuất bản là thành phần chính. Nó hoạt động như đăng ký cho callbacks / thính giả. Hãy xác định một người biết lắng nghe
& Nbsp; >>> máy in def (* event_args, ** event_keys):
& Nbsp; ... event_args in, event_keys
Để nhận được thông báo, khách hàng phải đăng ký với một nhà xuất bản. Điều này có thể đơn giản như
& Nbsp; >>> some_event.subscribe (máy in) #doctest: + dấu chấm lửng
& Nbsp;
Kết quả của các cuộc gọi đến đăng ký là một thể hiện của (một số lớp con của) lớp Subscription. Giá trị này có thể được sử dụng sau này, để hủy đăng ký, khi thông báo là không còn mong muốn. Các lớp con thực sự là một chi tiết thực hiện bạn nên thường không quan tâm. Tất cả bạn cần biết (và được phép dựa trên, trên thực tế), rằng nó sẽ là một thể hiện của lớp Subscription, và nó sẽ cung cấp bất cứ điều gì đã được ghi nhận như API công cộng của lớp đó (ngay bây giờ: chỉ có phương pháp hủy bỏ) .
Bây giờ, chúng ta hãy báo hiệu một sự kiện và xem những gì sẽ xảy ra:
& Nbsp; >>> some_event.publish ('một sự kiện')
& Nbsp; ('một sự kiện',) {}
Như bạn có thể thấy, các máy in đã được thông báo về sự kiện này, và duefully in các đối số của nó trên bàn điều khiển.
Hủy đăng ký
Như đã đề cập, kết quả của gọi đăng ký là một đối tượng thuê bao đặc biệt, đại diện cho các đăng ký của người nghe với các nhà xuất bản.
& Nbsp; >>> s1 = some_event.subscribe (máy in)
& Nbsp; >>> some_event.publish ('một sự kiện')
& Nbsp; ('một sự kiện',) {}
& Nbsp; ('một sự kiện',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Đúng
& Nbsp; >>> some_event.publish ('yet-một-một')
& Nbsp; ('yet-một-một',) {}
Các nhà xuất bản được hoàn toàn tái ký dự thi. Điều đó có nghĩa, bạn có thể đăng ký sự kiện từ bên trong một người biết lắng nghe, và bạn có thể hủy đăng ký trong bối cảnh đó là tốt:
& Nbsp; >>> def make_canceller (subs):
& Nbsp; ... def nghe (* unused_1, ** unused_2):
& Nbsp; ... print "Hủy bỏ", tàu ngầm, subs.cancel ()
& Nbsp; ... trở lại nghe
& Nbsp; >>> s1 = some_event.subscribe (máy in)
& Nbsp; >>> s2 = some_event.subscribe (make_canceller (s1))
& Nbsp; >>> some_event.publish ('gotta đi') #doctest: + dấu chấm lửng
& Nbsp; ('gotta đi',) {}
& Nbsp; ('gotta đi',) {}
& Nbsp; Hủy
& Nbsp; >>> some_event.publish ('biến mất') #doctest: + dấu chấm lửng
& Nbsp; ('ra đi',) {}
& Nbsp; Hủy
& Nbsp; >>> s1.cancel ()
& Nbsp; False
Kết quả của các cuộc gọi để hủy bỏ cho chúng ta biết, rằng các thuê bao đã được hoàn tác trước khi gọi (bằng cách nghe hủy ma thuật của chúng tôi). Nói chung, kêu gọi hủy bỏ nhiều lần là vô hại; tất cả, nhưng các cuộc gọi đầu tiên được bỏ qua.
Bây giờ chúng ta loại bỏ sự kỳ diệu I-thể-bỏ-stuff nghe và di chuyển trên:
& Nbsp; >>> s2.cancel ()
& Nbsp; Đúng
Sử dụng Non-Callables như callbacks
Bất cứ khi nào chúng tôi đã đăng ký ở trên, chúng tôi thực sự Giản điều một chút. Các chữ ký đầy đủ của phương pháp này là:
& Nbsp; def đăng ký (listener [, phương pháp [, reference_retention]])
Hãy cùng khám phá những lý luận phương pháp đầu tiên. Đến nay, chúng tôi chỉ sử dụng đối tượng chức năng như nghe. Về cơ bản, trên thực tế, chúng ta có thể sử dụng bất kỳ đối tượng có thể được gọi. Hãy nhớ rằng, bất kỳ đối tượng là "có thể được gọi" trong Python, nếu nó cung cấp một phương pháp __call__, vì vậy đoán, giá trị mặc định của các đối số phương pháp là gì?
& Nbsp; >>> s1 = some_event.subscribe (máy in, phương pháp = '__ call__')
& Nbsp; >>> some_event.publish ('foo')
& Nbsp; ('foo',) {}
& Nbsp; ('foo',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Đúng
Không có gì mới. Vì vậy, bây giờ bạn có thể hỏi: khi nào tôi sử dụng một tên phương thức khác nhau?
& Nbsp; >>> lớp mục tiêu (đối tượng):
& Nbsp; ... def __init __ (self, tên):
& Nbsp; ... self.name = tên
& Nbsp; ... def _callback (self, * args, ** phím):
& Nbsp; ... in self.name, args, phím
& Nbsp; >>> s1 = some_event.subscribe (Target ('foo'))
& Nbsp; >>> some_event.publish ('! Bumm') #doctest: + dấu chấm lửng
& Nbsp; Traceback (gần đây nhất gọi cuối cùng):
& Nbsp; ...
& Nbsp; Lỗi Loại: 'Target' đối tượng không thể được gọi
Rất tiếc. Hãy loại bỏ những người phạm tội, trước khi ai đó nhận thấy sai lầm của chúng tôi:
& Nbsp; >>> s1.cancel ()
& Nbsp; Đúng
& Nbsp; >>> s1 = some_event.subscribe (Target ('foo'), method = "_ callback ')
& Nbsp; >>> some_event.publish ('tác phẩm')
& Nbsp; ('! Chân công trình,) {}
& Nbsp; foo (công trình! ',) {}
Reference Retention
Vì vậy, đó là điều đó. Hiện vẫn còn là một cuộc tranh cãi chưa được khám phá để đăng ký lại, mặc dù: reference_retention. Cái tên nghe nguy hiểm, nhưng nó làm gì?
& Nbsp; >>> listener = Target ('ngon')
& Nbsp; >>> s2 = some_event.subscribe (listener, method = "_ callback ', reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ('yow',) {}
& Nbsp; foo ('yow',) {}
& Nbsp; ngon ('yow',) {}
Hm. Cho đến nay, không có sự khác biệt. Hãy thực hiện một thay đổi đơn giản:
& Nbsp; >>> listener = None
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ('yow',) {}
& Nbsp; foo ('yow',) {}
Ah. Được. Nghe ngon của chúng tôi đã biến mất. Chuyện gì đã xảy ra? Vâng, bằng cách xác định một chính sách duy trì tham chiếu của YẾU, chúng tôi nói với các nhà xuất bản, mà nó phải sử dụng một tham chiếu yếu để người nghe chỉ cần cài đặt, thay vì tham chiếu mạnh mặc định. Và sau khi chúng tôi phát hành chỉ có tham chiếu mạnh khác được biết đến người nghe bằng cách đặt người nghe để Không, người nghe đã thực sự loại bỏ từ các nhà xuất bản. Lưu ý, BTW., Rằng ví dụ trên có thể thất bại với việc triển khai python khác hơn CPython, do các chính sách khác nhau liên quan đến thu gom rác thải với. Các nguyên tắc nên vẫn còn hiệu lực, mặc dù, trong Jython cũng như IronPython, nhưng trong những hiện thực, không có đảm bảo, mà người nghe được loại bỏ ngay khi tham chiếu cuối cùng để nó giảm xuống.
Tất nhiên, điều này tất cả các công trình quá, nếu các phương pháp được gọi là mặc định một: __call__:
& Nbsp; >>> def make_listener (tên):
& Nbsp; ... def nghe (* args, ** phím):
& Nbsp; ... tên in, args, phím
& Nbsp; ... trở lại nghe
& Nbsp; >>> listener = make_listener ('yếu')
& Nbsp; >>> s2 = some_event.subscribe (listener, reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('sự kiện')
& Nbsp; ('sự kiện',) {}
& Nbsp; foo ('sự kiện',) {}
& Nbsp; yếu ('sự kiện',) {}
& Nbsp; >>> listener = None
& Nbsp; >>> some_event.publish ('sự kiện')
& Nbsp; ('sự kiện',) {}
& Nbsp; foo ('sự kiện',) {}
Đó là tất cả những gì cần biết về thư viện. Như tôi đã nói ở trên: đó là đơn giản, và có thể không có ích cho tất cả scenarioes và các trường hợp sử dụng, nhưng nó có những gì nó đã được viết đến.
Lỗi xử lý
Lớp Nhà xuất bản không có ý định để được subclassed. Nếu bạn cần phải điều chỉnh hành vi, bạn sử dụng các đối tượng chính sách / callbacks, được truyền cho constructor. Ngay bây giờ, có một chính sách điều chỉnh duy nhất, cụ thể là, hành vi của các nhà xuất bản trong trường hợp, người nghe tăng trường hợp ngoại lệ:
& Nbsp; >>> def toobad (sự kiện):
& Nbsp; ... nếu sự kiện == 'nâng':
& Nbsp; ... tăng ValueError
& Nbsp; >>> s1 = some_event.subscribe (toobad)
& Nbsp; >>> some_event.publish ('vô hại')
& Nbsp; ('vô hại',) {}
& Nbsp; foo ('vô hại',) {}
& Nbsp; >>> some_event.publish ('nâng')
& Nbsp; Traceback (gần đây nhất gọi cuối cùng):
& Nbsp; ...
& Nbsp; ValueError
Như bạn có thể thấy, hành vi mặc định là để tái nâng cao ngoại lệ từ bên trong xuất bản. Điều này có thể không thích hợp tùy thuộc vào các trường hợp sử dụng. Đặc biệt, nó sẽ ngăn chặn bất kỳ người nghe đăng ký sau đó để được chạy. Vì vậy, hãy định nghĩa xử lý lỗi riêng của chúng tôi:
& Nbsp; >>> def log_error (ngoại lệ, giá trị, traceback, thuê bao, args, phím):
& Nbsp; ... print "bị bắt", ngoại lệ
& Nbsp; >>> xuất bản = Nhà xuất bản (exception_handler = log_error)
& Nbsp; >>> publisher.subscribe (toobad) #doctest: + dấu chấm lửng
& Nbsp;
& Nbsp; >>> publisher.subscribe (máy in) #doctest: + dấu chấm lửng
& Nbsp;
& Nbsp; >>> publisher.publish ('vô hại')
& Nbsp; ('vô hại',) {}
& Nbsp; >>> publisher.publish ('nâng')
& Nbsp; bắt
& Nbsp; ('tăng',) {}
Là một thay thế để cung cấp bộ xử lý lỗi ở thời gian thi công, bạn cũng có thể cung cấp một trình xử lý lỗi khi xuất bản một sự kiện, như vậy:
& Nbsp; >>> def log_error_2 (ngoại lệ, giá trị, traceback, thuê bao, args, phím):
& Nbsp; ... print "bị bắt", ngoại trừ "trong ấn phẩm"
& Nbsp; >>> publisher.publish_safely (log_error_2, 'tăng')
& Nbsp; bắt
& Nbsp; ('tăng',) {}
Như bạn có thể thấy, các lỗi xử lý cho mỗi cuộc gọi được ưu tiên hơn xử lý lỗi mặc định của nhà xuất bản. Lưu ý, mà không có xâu chuỗi, tức là, nếu xử lý lỗi cho mỗi cuộc gọi đặt ra một ngoại lệ, xử lý mặc định của nhà xuất bản không được gọi, nhưng ngoại trừ đơn giản là tuyên truyền ra bên ngoài cho người gọi của publish_safely: các nhà xuất bản không có cách nào để phân biệt giữa trường hợp ngoại lệ được nêu lên vì các handler muốn hủy bỏ các công văn và các ngoại lệ nêu ra bởi tai nạn, vì vậy tất cả các ngoại lệ nêu ra bởi việc xử lý chỉ đơn giản là chuyển tiếp đến các ứng dụng client.
Chủ đề An toàn
Thư viện này được hoàn toàn sợi nhận thức và đề an toàn. Vì vậy, đăng ký vào một người biết lắng nghe chia sẻ trên nhiều chủ đề được an toàn, và do đó là hủy bỏ đăng ký
là gì mới trong phiên bản này:.
- Subscription xử lý với doanh nghiệp cung cấp truy cập đến các đối tượng người nghe họ và tên phương pháp. Điều này đã được bổ sung, vì lợi ích của mã xử lý lỗi, mà muốn để đăng nhập ngoại lệ và cung cấp một cách tốt hơn để xác định người nghe thực tế, mà đã đi rogue.
là gì mới trong phiên bản 0.2:
- Lỗi xử lý đã được thay đổi. Thay vì lớp con của nhà xuất bản, xử lý ngoại lệ mặc định là doanh nghiệp thông qua như là gọi lại cho nhà xuất bản trong quá trình xây dựng. Lớp Nhà xuất bản hiện nay được ghi nhận như & quot; không được dự định để được subclassed & quot;.
Yêu cầu :
- Python
Bình luận không