Reputation: 332
I've found many questions on StackOverflow that come close to solving my problem but none that quite do it. I have a class in Python and I would like to split its methods up so that I can use the class in the following way:
my_greeter = Greeter(name='Bob')
my_greeter.sayHello()
#> "Hello Bob"
my_greeter.international.sayHola()
#> "Hola Bob"
I'm not quite sure how to structure my files and their contents to achieve this. Could someone please give an example?
Note: An example of this behaviour in the wild is pandas.Series.str.contains()
although the source code was too dense for me to pick apart how they did this.
Upvotes: 2
Views: 1313
Reputation: 111
I came across this while looking for a way to group methods. The accepted answer (fluent design) is great for chaining methods - where each .method
is doing something - but I found a simpler option for simply grouping things together for organisational reasons:
from types import SimpleNamespace
class Example():
def __init__(self):
self.property1 = "foo"
self.property2 = "bar"
self.group1 = SimpleNamespace()
self.group1.property3 = 1.23
self.group1.property4 = 4.56
Upvotes: 1
Reputation: 42097
This is an example of Fluent API design, which uses method chaining in it's core. The implementation idea of this in Python is to return the instance from each method after doing what they are supposed to do.
Here is a naive example:
In [1]: class Fluent:
...: def __init__(self, num):
...: self.num = num
...: def add_two(self):
...: self.num += 2
...: return self # this allows us for chaining
...: def result(self):
...: return self.num
...:
In [2]: f = Fluent(10)
In [3]: f.add_two().result()
Out[3]: 12
You can make add_two
a property
to avoid the method call, and refer as an attribute:
f.add_two.result()
Edit: Example with property
:
In [4]: class Fluent:
...: def __init__(self, num):
...: self.num = num
...: @property
...: def add_two(self):
...: self.num += 2
...: return self # this allows us for chaining
...: def result(self):
...: return self.num
...:
In [5]: f = Fluent(10)
In [6]: f.add_two.result()
Out[6]: 12
Upvotes: 2
Reputation: 1147
One way to do this would be to import a module named international
into your so called Greeter
class. Then, you could do things as normal and put your methods under the international
namespace into a different file. In your case:
# main.py
class Greeter:
import international # To import the international file's contents into the class
def __init__(self, name="someone"):
self.name = name
def sayHello(self):
print(f"Hello {self.name}")
And the international file:
# international.py
def sayHola(self):
print(f"Hola {self.name}")
Some notes:
Always add self
as the first argument in every method you define in international.py
When you import the files into a class when the method is run the function automatically has self
passed to it
If you need helper functions that you do not want to be used by the user I would recommend you put them in a different file (and import them inside the method)
Upvotes: -1