Reputation: 44545
I'd like to the make a clean, "smart" method that performs specific operations without passing in arguments. I have some code that works in principle as follows:
class Foo():
def __init__(self, spam='spam', ham='ham'):
self.spam = spam
self.ham = ham
def bar(self, arg):
# spam operation
if arg == self.spam:
return self.spam*2
# ham operation
elif arg == self.ham:
return self.ham*3
Notice the bar
method is written to perform different operations on spam
and ham
. Implementing this code would return:
foo = Foo()
foo.bar(foo.spam) # returns 'spamspam'
foo.bar(foo.ham) # returns 'hamhamham'
Unfortunately, I'm having to use foo
twice to access a specific operation in bar
, which is awkward and tedious. Is there a cleaner, Pythonic way to get the same results without passing in arguments? For example, is it possible to overload the dot (.) operator to the get the same results with:
# Ideal 1
foo = Foo()
foo.bar.spam # bar knows to use spam operation
foo.bar.ham # bar knows to use ham operation
or even better
# Ideal 2
foo = Foo()
foo.spam.bar # bar knows to use spam operation
foo.ham.bar # bar knows to use ham operation
Upvotes: 4
Views: 3360
Reputation: 5805
EDIT: Updated to parametize the options.
Here is something using object composition:
class Pork(object):
def __init__(self, name, mult):
self.name = name
self.mult = mult
@property
def bar(self):
return self.name * self.mult
def __repr__(self):
return self.name
class Foo(object):
def __init__(self, spam='spam', ham='ham'):
self.spam = Pork(spam, 2)
self.ham = Pork(ham, 3)
Results:
In [638]: foo = Foo()
In [639]: foo.spam.bar
Out[639]: 'spamspam'
In [641]: foo.ham.bar
Out[641]: 'hamhamham'
Upvotes: 2