Reputation: 26160
So I need to mutate a method at object initialization based upon input to __init__
(for those interested, I'm changing the navigate_to
method in a test framework based upon which type of automator is being instantiated (Selenium, mobile device automator, etc)). I've come up with a solution using a conditionally created closure in __init__
, but it seems like there should be a more elegant and optimized way to do this. As an example of the approach:
class Foo(object):
def __init__(self, x):
self.x = x
if x % 2:
def odd_or_even():
return '%d odd' % self.x
else:
def odd_or_even():
return '%d even' % self.x
self.odd_or_even = odd_or_even
Resulting in:
>>> foo1 = Foo(1)
>>> foo2 = Foo(2)
>>> foo1.odd_or_even()
'1 odd'
>>> foo2.odd_or_even()
'2 even'
This works, but I feel like there should be some better way to do this. Suggestions?
Upvotes: 2
Views: 125
Reputation: 56674
I would suggest delegating this - something like
class Automator(object):
def navigate_to(self, url):
pass
class SeleniumAutomator(Automator):
def navigate_to(self, url):
# do it the Selenium way
pass
class MobileAutomator(Automator):
def navigate_to(self, url):
# do it the mobile-browser way
pass
class Foo(object):
def __init__(self, x, automator):
self.x = x
self.automator = automator
def navigate_to(self, url):
return self.automator.navigate_to(url)
f = Foo(3, SeleniumAutomator())
f.navigate_to('http://www.someplace.org/')
... you could do this just with functions, but I presume there are a bunch of interface-dependent methods, and it seems cleanest to keep them grouped in a class.
Edit: oh - then what you want isn't a Foo, it's an automator factory - something like
def makeAutomator(type, *args, **kwargs):
return {
"selenium": SeleniumAutomator,
"mobile": MobileAutomator
}[type](*args, **kwargs)
myauto = makeAutomator("selenium")
Upvotes: 3
Reputation: 71535
I would make a different method for each type of automator, and then a generic method that uses the state of self
to determine which of the specific methods to call.
Why do you need to create a closure containing the decision, when you can just record the decision in self
?
Upvotes: 1