What's the best way to organize a Python class? [closed] - python

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'd like to know what's the best way to organize a class in Python as checking on previous questions here I didn't find exactly what I needed. Let's say I have this class:
class A():
def __init__(self):
self.data = #A pandas dataframe I get from an online API
I have then many functions inside this class which I'd like to organize. All these functions will need the Dataframe contained in self.data as parameter.
I thought to create a subclass for every group of functions but I didn't find a way to then refer to self.data from inside the subclass.
I found then online that I could organize the functions in different modules. However how to I pass the Dataframe in self.data as parameter to the functions? Let's say function1 is defined as following:
def function1(self):
print (self.data)
If the function was defined inside the class, I could do this:
x = A()
x.function1()
and get the print without passing self.data as parameter. How would I do this if a function is defined in another module and I import it in the main class without passing self.data as parameter every time? Thanks in advance.
EDIT:
If I do:
class A():
def __init__(self):
self.x = 1
self.b = self.B()
class B(A):
def print(self):
print(self.x)
I get an error saying "A is not defined"

I like your approach to create subclasses for each group of methods. First start with a base class which stores your data
class DataBase:
def __init__(self, data):
self._data = data
Then write your different groups of methods ...
class GroupB(DataBase):
def func_b1(self):
return self._data
def func_b2(self):
return self._data
class GroupA(DataBase):
def func_a1(self):
return self._data
def func_a2(self):
return self._data
... and finally collect all these groups together
class MyData(GroupA, GroupB):
pass
>>> d = MyData(123)
>>> d.func_a1()
123
>>> d.func_b2()
123
I hope this helps you.

Related

Can you access attributes that were created with the init method from other methods in the class? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
When I write the __init__ method and assign attributes, can I access those attributes in other methods (functions) that I write in that class? If so, how is it done?
I've googled this but couldn't find an answer. I Haven't been able to wrap my head around this one.
Use self:
class MyClass:
def __init__(self):
self.name = 'John'
def other_method(self):
print(self.name)
other_method will print "John".
When you make a class and set an instance (like first_class = MyClass()) the def __init__(self): is run or initialised. Any variables in there, like self.name are able to be accessed from within the class and its functions, as well as when you use a class in another program. self kinda attaches that variable to that class.
Basically using Allure's example:
class MyClass:
def __init__(self):
self.name = "John"
def show_name(self):
print(self.name)
Then use MyClass's name outside of class, in a program:
firstClass = MyClass()#Initialise MyClass and its variables
print(firstClass.name)
Or:
firstClass= MyClass()
firstClass.show_name()
Both output:
'John'
(still putting up this answer for others, hope you don't mind :) )

What the purpose of creating class instance attibutes directly in the code [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Pyhon allows to create any class instance attribute just like new variable and you don't need to define them in class definition.
What's the purpose of that?
class MyClass:
def __init__(self):
pass
obj = MyClass()
obj.a = '1';
print(obj.a)
#>> 1
P.S.
found interesting example of such kind of usage
Can you use a string to instantiate a class
There dynamically created attributes used to store dynamically instatiated classes
The purpose of this is simplicity: There is no difference to accessing an instance inside or outside of a method. The object seen inside and outside of a method is completely equivalent, and by extension the same rules apply anywhere:
class MyClass:
def __init__(self):
print(self) # <__main__.MyClass object at 0x119636490>
self.b = 12 # assign to an instance
obj = MyClass()
print(obj) # <__main__.MyClass object at 0x119636490>
obj.b = 12 # # assign to an instance
Note that one can read and write attributes inside and outside methods, and these attributes are visible inside and outside of methods. In fact, Python has no concept of "inside" and "outside" of methods, aside from a few code-rewrites such as double-underscore name mangling.
This is both a result and the enabling feature to allow various inbuilt features of other languages to work without explicit support. For example, Python allows the equivalent of extension methods without extra syntax/functionality:
class MyPoint:
def __init__(self, x, y):
self.x, self.y = x, y
# Oops, forgot a repr!
def my_point_repr(self):
return f'{self.__class__.__name__}(x={self.x}, y={self.y})'
MyPoint.__repr__ = my_point_repr
print(MyPoint(1, 2)) # MyPoint(x=1, y=2)

Calling methods inside class to modify list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a class in which I collect data to list with the help of wide range of methods (say 23). Every method uses list and could modify it. My question is how can I call (in class, respectively) all methods of class in more generally accepted way?
class Example(object):
def __init__(self):
self.lst = []
def multiply(self):
for i in xrange(10):
self.lst.append(i**2)
def get_list(self):
return self.lst
# Calling:
ex = Example()
ex.multiply
print ex.get_list
# What I want is call multiply method inside class and just do this
print ex.get_list
Example class illustrates my idea. I know that it is possible to solve my problem through iterating with Example.__dict__values(), calling all methods in one class's method or with inspect module, but I am not sure that there are not more pure-Pythonic ways.
UPDATE:
All I want is to collect configuration data for yapf formatter.
The main problem is how to call all methods in class - I don't want to implement all configuration analysis of input file in one method. OOP and patterns is my guide.
UPDATE 2:
Answer for Jared Goguen. I want to create class to collect data to dictionary and send it to CreateStyleFromConfig method.
And when it will done, I want just to get get_style method from class without calling all methods inside it:
config = ConfData() # Class which collects all configurations from file
config.get_style()
ConfData class contains methods with specific for data name. For example:
def align_closing_bracket_with_visual_indent(self):
# Do some work..
pass
So, I guess there are two potential solution to this, but I don't really like either of them. I think you might be approaching the problem the wrong way.
You could use an external decorator track and a class variable tracker to keep track of which methods you want to call.
def track(tracker):
def wrapper(func):
tracker.append(func)
return func
return wrapper
class Example:
tracker = []
#track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
#track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
print Example().collect_data()
# {'key_b1': 'val_b1', 'key_b2': 'val_b2', 'key_a1': 'val_a1', 'key_a2': 'val_a2'}
With this approach, you can have utility methods in your class that you don't want to call.
Another approach would be to inspect the directory of your class and logically determine which methods you want to call.
from inspect import ismethod
class Example:
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and attr != 'collect_data':
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
This approach is similar to the one mentioned in your post (i.e. iterating over __dict__) and is weak because any instance methods that you don't want to call need to start with '_'. You can adapt this approach to use some other naming convention, but it might not be readable to anyone else.
Either of these methods could implement the collect_data portion as a super-class, allowing you to create minimal sub-classes. This doesn't really help much with the first approach.
class MethodTracker(object):
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
class Example(MethodTracker):
tracker = []
#track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
#track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
With the second approach, the resulting sub-class is minimal. Also, you can do a little reflection to allow the super-class to have utility methods that don't start with '_'.
from inspect import ismethod
class MethodTracker(object):
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and not hasattr(MethodTracker, attr):
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
def decoy_method(self):
return 'This is not added to data.'
class Example(MethodTracker):
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]

Difference between different ways to call static method from within class [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is there a difference in the two ways of calling a static method in the same class shown below?
class MyClass:
def __init__(self):
self.do_something() #or MyClass.do_something()?
#staticmethod
def do_something():
pass
More specifically, particularly in the cases of refactoring (changing class name) and inheritance (as static methods can be inherited and overridden in Python)?
I can only think of one situation in which it would make a difference; what about when you inherit from MyClass? Compare:
>>> class MyClass(object):
def __init__(self):
self.do_something()
#staticmethod
def do_something():
print "Base class"
>>> class SubClass(MyClass):
#staticmethod
def do_something():
print "Sub class"
>>> s = SubClass()
Sub class
with:
>>> class MyClass(object):
def __init__(self):
MyClass.do_something()
#staticmethod
def do_something():
print "Base class"
>>> class SubClass(MyClass):
#staticmethod
def do_something():
print "Sub class"
>>> s = SubClass()
Base class
This is a contrived example, but you should consider what you think the appropriate behaviour should be.
Your example of refactoring to change the class name is a good one, too; self doesn't have to be updated whenever you rename the class, whereas if you have explicit MyClass references you have to update them all (a good IDE will do this for you, but if you can avoid it that's better).

Is there a way to programatically determine the order in which functions are declared in a python module? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm working on a project where being able to discover the order of declaration of functions within a class would be quite useful. Basically, I'd like to be able to guarantee that all functions within a class are executed in the order they are declared.
The end result is a web page in which the order of the output of the functions matches the order in which the functions are declared. The class will inherit from a generic base class that defines it as a web page. The web application will dynamically load the .py file.
class Register(object):
def __init__(self):
self._funcs = []
def __call__(self, func):
self._funcs.append(func)
return func
class MyClass(object):
_register = Register()
#_register
def method(self, whatever):
yadda()
# etc
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in dir(cls) if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
Usage:
class Foo(object):
def a(): pass
def b(): pass
def c(): pass
print methods_in_order(Foo)
[<unbound method Foo.a>, <unbound method Foo.b>, <unbound method Foo.c>]
Also works on an instance:
print methods_in_order(Foo())
If any inherited methods were defined in a different source file, the ordering may not be consistent (since the sort relies upon each method's line number in its own source file). This could be rectified by manually walking the class's method resolution order. This would be a fair bit more complicated so I won't take a shot here.
Or if you want only the ones directly defined on the class, which seems like it might be useful for your described application, try:
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in (cls.__dict__ if type(cls) is type else type(cls).__dict__)
if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
This assumes a new-style class.

Categories