2016-11-25 3 views
0

Я хочу контролировать доступ к переменной. Я попытался реализовать его с помощью модуля pyjack, но метод pyjack.connect (my_str, proxyfn = my_proxyfn) генерирует исключение ...type '<type 'str'>' not supported.Есть ли механизм в Python, который позволит перехватить доступ к объекту?

Вот пример того, что я хочу:

>>> def on_access(obj): 
... print 'object with id=%d has been requested' % id(obj) 
... 
>>> s = 'some string' 
>>> 
>>> foo(s, handler=on_access) 
>>> 
>>> print s 
object with id=4559856664 has been requested 
some string 
>>> 
>>> s + '.' 
object with id=4559856664 has been requested 
some string. 

Upd: Важно, чтобы объект сохранил свой тип.

В продолжении примера:

>>> import json 
>>> 
>>> json.dumps(s) 
object with id=4559856664 has been requested 
'"some string"' 
+1

Не могли бы вы определить, что делает и не считается «доступом»? – wim

+0

Да, я не думаю, что приведенные вами примеры делают ваш вопрос ясным. –

+0

Похоже, вам просто нужна оболочка функции. 'def s(): print 'access'; return 'some string''. – TigerhawkT3

ответ

0

Там нет никакого способа сделать это без создания какого-то класса-оболочки, которая делегирует вызовы к лежащему в основе «гусеничного» объект.

Каждая операция над объектом в конечном итоге контролируется с помощью его пробоотборников. print, например, звонки __str__, s + '.' первые звонки __add__, абонентские звонки __getitem__. Вам необходимо определить поведение «по доступу» в этих функциях.

Быстрый основной рецензия, который представляет функциональность в ваших примерах может выглядеть следующим образом:

class Wrap(object): 

    access_str = "object with id={} has been accessed" 

    def __init__(self, obj): 
     self._obj = obj 

    def __add__(self, v): 
     print(self.access_str.format(self._obj)) 
     # If you want the result to be tracked 
     # return Wrap(self._obj + v) 
     return self._obj + v 


    def __repr__(self): 
     print(self.access_str.format(self._obj)) 
     return repr(self._obj) 

    def __str__(self): 
     print(self.access_str.format(self._obj)) 
     return str(self._obj) 

это, очевидно, не хватает остальной части методов, необходимых, но это то, что вы должны сделать, если вы идете вниз по этому маршруту.

Теперь вы взаимодействуете с ним, как вы бы с любой строкой:

>>> s = Wrap("Hello World") 
>>> print(s) 
object with id=140023929394880 has been accessed 
Hello World 
>>> s + '.' 
object with id=140023929394880 has been accessed 
'Hello World.' 

Это, очевидно, может быть изменен, например, в __init__ вы могли бы заставить требование для name аргумент, который вы бы затем связать в с использованием globals().

Кроме того, вы можете создать метакласс, который автоматически генерирует похожие методы dunder в зависимости от типа.

Точка есть, нет встроенного способа сделать это, вам нужно сделать это самостоятельно в некоторой утомительной манере.