Reputation: 378
I have something written in Perl/Moose that uses method modifiers (before/after/around) and I'm wondering what the "Pythonic" way of composing functionality into a method would be?
To expand, I have a data structure that needs to be processed, data is "tagged" to mark it in terms of how it should be processed. I check those tags and then dynamically build my processor accordingly. Using Perl's Moose I can pull in the "traits" I need and then run a single method to process the data. Each "Role" I pull in assumes there's a "process" method and it just bolts it's functionality on with an after 'process' => sub { }
. This way if I have a new type of data to deal with I can simply add another Role without having to touch any other code. All this specifically avoids any inheritance and is very simple to manage.
I thought about trying to recreate Moose's "method modifiers" using decorators and/or metaclasses, but I'm wondering what the idiomatic way would be in Python...
Thanks
Upvotes: 0
Views: 86
Reputation: 378
Just to expand on @LukasGraf answer pulling in contexts dynamically... (in Python 3)
from contextlib import ExitStack
class Manager1():
def __init__(self, data):
self.data = data
def __enter__(self):
print("entering 1... (data=%s)" % self.data)
return self
def __exit__(self, exc_type, exc_value, traceback):
print("exiting 1... (data=%s)" % self.data)
class Manager2():
def __init__(self, data):
self.data = data
def __enter__(self):
print("entering 2... (data=%s)" % self.data)
return self
def __exit__(self, exc_type, exc_value, traceback):
print("exiting 2... (data=%s)" % self.data
contexts = [Manager2('test'), Manager1('test')]
with ExitStack() as stack:
[ stack.enter_context(context) for context in contexts ]
print('here')
generates...
entering 2... (data=test)
entering 1... (data=test)
here
exiting 1... (data=test)
exiting 2... (data=test)
Upvotes: 0
Reputation: 32640
I hardly know any Perl, but from looking at the first example in the MethodModifier docs, it seems to me context managers in Python would be the thing that most resembles Moose's method modifiers:
class MyContextManager(object):
def __init__(self, data):
self.data = data
def __call__(self):
print 'foo'
def __enter__(self):
print "entering... (data=%s)" % self.data
# this will be bound to the name after the 'as' clause
return self
def __exit__(self, exc_type, exc_value, traceback):
print "exiting... (data=%s)" % self.data
with MyContextManager('bar') as manager:
print "before"
manager()
print "after"
Output:
entering... (data=bar)
before
foo
after
exiting... (data=bar)
Unfortunately, documentation for context managers is a bit spread out:
Upvotes: 1