以下のコード中のclass GenericWrapper内のコードで分からないところがあります。
Python2.4
1#! /usr/bin/env python 2# coding=utf-8 3 4def wrap_callable(any_callable, before, after): 5 ''' あらゆる呼び出し可能型(callable)を前後にコールを入れる形でラップする ''' 6 def _wrapped(*a, **kw): 7 before() 8 try: 9 return any_callable(*a, **kw) 10 finally: 11 after() 12 _wrapped.__name__ = any_callable.__name__ 13 return _wrapped 14 15import inspect 16 17class GenericWrapper(object): 18 ''' オブジェクトのメソッド全てを前後にコールに入れる形でラップする ''' 19 def __init__(self, obj, before, after, ignore=()): 20 # __setattr__をバイパスするため__dict__に直接セットするのが必須 21 # ゆえにダブルアンダースコア名のためname-manglingの再生成が必要 22 clasname = 'GenericWrapper' 23 self.__dict__['_{}__methods'.format(clasname)] = {} 24 self.__dict__['_{}__obj'.format(clasname)] = obj 25 for name, method in inspect.getmembers(obj, inspect.ismethod): 26 if name not in ignore and method not in ignore: 27 self.__methods[name] = wrap_callable(method, before, after) 28 29 def __getattr__(self, name): 30 try: 31 return self.__methods[name] 32 except KeyError: 33 return getattr(self.__obj, name) 34 35 def __setattr__(self, name, value): 36 setattr(self.__obj, name, value) 37 38class SynchronizedObject(GenericWrapper): 39 ''' オブジェクトとその全メソッドを同期機構でラップする ''' 40 def __init__(self, obj, ignore=(), lock=None): 41 if lock is None: 42 import threading 43 lock = threading.RLock() 44 GenericWrapper.__init__(self, obj, lock.acquire, lock.release, ignore) 45 46if __name__ == '__main__': 47 import threading 48 import time 49 class Dummy(object): 50 def foo(self): 51 print("Foo") 52 time.sleep(1) 53 def bar(self): 54 print("Bar") 55 def baaz(self): 56 print("Baaz") 57 tw = SynchronizedObject(Dummy(), ignore=['baaz']) 58 threading.Thread(target=tw.foo).start() 59 time.sleep(0.1) 60 threading.Thread(target=tw.bar).start() 61 time.sleep(0.1) 62 threading.Thread(target=tw.baaz).start() 63
ここで、2点分からないことがあります。
❶以下のコメント部が何を言っているのかが分かりません。
# __setattr__をバイパスするため__dict__に直接セットするのが必須 # ゆえにダブルアンダースコア名のためname-manglingの再生成が必要
❷self.__methods
とself.__obj
が何なのか分かりません。
self.__dict__['_GenericWrapper__methods']
などと関連があるのでしょうか?
アドバイス頂けたらありがたいです。
宜しくお願いします。
ちなみに上記のコードが書かれている書籍には以下のようなことが書かれています。
このレシピではオブジェクト属性への直接アクセス(getやset)をラップしていない。オブジェクトのロックを考慮しつつ直接アクセスがしたい場合、ラッパーの特殊メソッド__getattr__および__setattr__でそれぞれのビルトイン関数getattrおよびsetattrをコールする周辺にtry/finallyのロッキング・イディオムを加える必要がある。
回答1件
あなたの回答
tips
プレビュー