Slave to master auto linking.

  • Thread starter Богун Дмитрий
  • Start date
Ð

Богун Дмитрий

Hello.
I try make some weird thing. I want to get from code like this:
class master:
...
class slave:
...

m = master()
s = m.slave()
s.master is m

Last expression must be true. I want link "master" to be set
automatically by master object while creating slave object. Additional
requirement - "master" link must be available for constructor of slave
object.

Best what I can get is:

import functools
from weakref import WeakKeyDictionary
from threading import RLock

class meth_wrap(object):
def __init__(self, func):
object.__init__(self)
self.func = func
functools.update_wrapper(self, func, updated=())

class lazy_attr(meth_wrap):
def __get__(self, obj, type=None):
if obj is None:
return self
val = self.func(obj)
setattr(obj, self.__name__, val)
return val

class slave_mixin(object):
@lazy_attr
def master(self):
m = slave_gen._unbound_master
assert m is not None, '"Slave" object can\'t find master link.
Is it was correctly created? obj:%s' % repr(self)
return m

class slave_gen(meth_wrap):
_storage = WeakKeyDictionary()
# ИÑпользуетÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾
_unbound_master = None
_lock = RLock()

def __get__(self, mobj, type=None):
if mobj is None:
return self.func
d = {
'm': mobj,
'w': self}
obj = self.delay_init()
self._storage[obj] = d
functools.update_wrapper(obj, self.func, updated=())
return obj

class delay_init(object):
def __call__(self, *args, **kw_args):
d = slave_gen._storage[self]
slave_gen._lock.acquire()
try:
slave_gen._unbound_master = d['m']
obj = d['w'].func(*args, **kw_args)
obj.master = d['m']
slave_gen._unbound_master = None
finally:
slave_gen._lock.release()
return obj

def __getattr__(self, attr):
d = slave_gen._storage[self]
return getattr(d['m'], attr)
def __setattr__(self, attr, val):
d = slave_gen._storage[self]
return setattr(d['m'], attr, val)

class Master(object):
@slave_gen
class Slave(slave_mixin):
def __init__(self):
slave_mixin.__init__(self)
print 'Slave.__init__: self.master: ', self.master

if __name__ == '__main__':
m = Master()
s = m.Slave()
print 's.master: ', s.master

It works, by looking little weird... and I can't find way to escape from
using lock at object creation phase. It can be done by adding mandatory
attribute to slave class constructor, but this is even worse(for me)
than using lock.

Please show me more clear way to make this slave to master link.

PS Sorry for my English.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top