Is it good style to create a separate method, in which I preprocess data, before I pass it to the constructor (in case the preprocessing is cumbersome), like so:
class C():
def __init__(self, input, more_input):
self.value = self.prepare_value(input, more_input)
def prepare_value(self, input, more_input):
#here I actually do some nontrivial stuff, over many lines
#for brevity I'm illustrating just a short, one-line operation
value = (input + more_input)/2
return value
print(C(10, 33).value) # has value 21.5
If you wanted to do it like this, then I'd suggest two things.
Make the prepare_value() method a static method by decorating with the #staticmethod decorator. Since it's not making any changes to the instance of the class itself, just returning a value then you shouldn't be making it a method of the instance. Hence, #staticmethod.
Signify that the method should only be used internally by using the name _prepare_value(). This doesn't actually make it private, but it's a well recognized convention to say to other developers (i.e. future you) "this method isn't designed to be used externally".
Overall my suggestion would be:
class C():
def __init__(self, input, more_input):
self.value = self._prepare_value(input, more_input)
#staticmethod
def _prepare_value(input, more_input):
value = (input + more_input)/2
return value
Related
Is this a plausible and sound way to write a class where there is a syntactic sugar #staticmethod that is used for the outside to interact with? Thanks.
###scrip1.py###
import SampleClass.method1 as method1
output = method1(input_var)
###script2.py###
class SampleClass(object):
def __init__(self):
self.var1 = 'var1'
self.var2 = 'var2'
#staticmethod
def method1(input_var):
# Syntactic Sugar method that outside uses
sample_class = SampleClass()
result = sample_class._method2(input_var)
return result
def _method2(self, input_var):
# Main method executes the various steps.
self.var4 = self._method3(input_var)
return self._method4(self.var4)
def _method3(self):
pass
def _method4(self):
pass
Answering to both your question and your comment, yes it is possible to write such a code but I see no point in doing it:
class A:
def __new__(cls, value):
return cls.meth1(value)
def meth1(value):
return value + 1
result = A(100)
print(result)
# output:
101
You can't store a reference to a class A instance because you get your method result instead of an A instance. And because of this, an existing __init__will not be called.
So if the instance just calculates something and gets discarded right away, what you want is to write a simple function, not a class. You are not storing state anywhere.
And if you look at it:
result = some_func(value)
looks exactly to what people expect when reading it, a function call.
So no, it is not a good practice unless you come up with a good use case for it (I can't remember one right now)
Also relevant for this question is the documentation here to understand __new__ and __init__ behaviour.
Regarding your other comment below my answer:
defining __init__ in a class to set the initial state (attribute values) of the (already) created instance happens all the time. But __new__ has the different goal of customizing the object creation. The instance object does not exist yet when __new__is run (it is a constructor function). __new__ is rarely needed in Python unless you need things like a singleton, say a class A that always returns the very same object instance (of A) when called with A(). Normal user-defined classes usually return a new object on instantiation. You can check this with the id() builtin function. Another use case is when you create your own version (by subclassing) of an immutable type. Because it's immutable the value was already set and there is no way of changing the value inside __init__ or later. Hence the need to act before that, adding code inside __new__. Using __new__ without returning an object of the same class type (this is the uncommon case) has the addtional problem of not running __init__.
If you are just grouping lots of methods inside a class but there is still no state to store/manage in each instance (you notice this also by the absence of self use in the methods body), consider not using a class at all and organize these methods now turned into selfless functions in a module or package for import. Because it looks you are grouping just to organize related code.
If you stick to classes because there is state involved, consider breaking the class into smaller classes with no more than five to 7 methods. Think also of giving them some more structure by grouping some of the small classes in various modules/submodules and using subclasses, because a long plain list of small classes (or functions anyway) can be mentally difficult to follow.
This has nothing to do with __new__ usage.
In summary, use the syntax of a call for a function call that returns a result (or None) or for an object instantiation by calling the class name. In this case the usual is to return an object of the intended type (the class called). Returning the result of a method usually involves returning a different type and that can look unexpected to the class user. There is a close use case to this where some coders return self from their methods to allow for train-like syntax:
my_font = SomeFont().italic().bold()
Finally if you don't like result = A().method(value), consider an alias:
func = A().method
...
result = func(value)
Note how you are left with no reference to the A() instance in your code.
If you need the reference split further the assignment:
a = A()
func = a.method
...
result = func(value)
If the reference to A() is not needed then you probably don't need the instance too, and the class is just grouping the methods. You can just write
func = A.method
result = func(value)
where selfless methods should be decorated with #staticmethod because there is no instance involved. Note also how static methods could be turned into simple functions outside classes.
Edit:
I have setup an example similar to what you are trying to acomplish. It is also difficult to judge if having methods injecting results into the next method is the best choice for a multistep procedure. Because they share some state, they are coupled to each other and so can also inject errors to each other more easily. I assume you want to share some data between them that way (and that's why you are setting them up in a class):
So this an example class where a public method builds the result by calling a chain of internal methods. All methods depend on object state, self.offset in this case, despite getting an input value for calculations.
Because of this it makes sense that every method uses self to access the state. It also makes sense that you are able to instantiate different objects holding different configurations, so I see no use here for #staticmethod or #classmethod.
Initial instance configuration is done in __init__ as usual.
# file: multistepinc.py
def __init__(self, offset):
self.offset = offset
def result(self, value):
return self._step1(value)
def _step1(self, x):
x = self._step2(x)
return self.offset + 1 + x
def _step2(self, x):
x = self._step3(x)
return self.offset + 2 + x
def _step3(self, x):
return self.offset + 3 + x
def get_multi_step_inc(offset):
return MultiStepInc(offset).result
--------
# file: multistepinc_example.py
from multistepinc import get_multi_step_inc
# get the result method of a configured
# MultiStepInc instance
# with offset = 10.
# Much like an object factory, but you
# mentioned to prefer to have the result
# method of the instance
# instead of the instance itself.
inc10 = get_multi_step_inc(10)
# invoke the inc10 method
result = inc10(1)
print(result)
# creating another instance with offset=2
inc2 = get_multi_step_inc(2)
result = inc2(1)
print(result)
# if you need to manipulate the object
# instance
# you have to (on file top)
from multistepinc import MultiStepInc
# and then
inc_obj = MultiStepInc(5)
# ...
# ... do something with your obj, then
result = inc_obj.result(1)
print(result)
Outputs:
37
13
22
I am new to opp programming.I wanted to know what to do with a function that is inside the class but does not use self value
For example
class example:
def __init__(self,n):
self.number=n
def get_t(self,t):
return t*t
def main(self):
b=1
k=self.get_t(b)
From the example the function get_t has nothing to do with self value.
So I wanted to know where to place the function get_t or may be how to restructure the class.
Thank you for your consideration
What you're looking for are static methods. To declare a method static do it like this
#staticmethod
def foo():
pass
Nothing. Just let it be, Python won't complain about it and there's nothing fundamentally wrong about methods that doesn't use its instance. If your linter complains about it, you can shut up that warning. These kind of helper functions are often intended to be private methods that aren't intended to be used externally, you may want to prefix the name with underscore to indicate that.
Convert it into a free function. Python is an OOP language, but it's also a mixed paradigm language, unlike Java, for example, you can actually create a function outside of a class declaration. Pythonic code does not necessarily means putting everything into classes, and often a free function is perfectly suitable place for functions that doesn't involve a particular object instance.
def get_t(t):
return t*t
class example:
def main(self):
b=1
k=self.get_t(b)
If you want to be able to call it from the class by doing Example.get_t(blah) without having to have an instance, then you can either use the staticmethod or classmethod decorator. I suggest using classmethod which can do everything that staticmethod can do while the reverse isn't true and it's easier to make classmethod work correctly when you need to override it in a multi inheritance situation. staticmethod has a very tiny performance advantage, but you're microoptimizing if that's your concern.
class example:
#classmethod
def get_t(cls, t):
return t*t
def main(self):
b=1
k=self.get_t(b)
If get_t() is only being called from one method, you can put it as an inner function of that method:
class example:
def main(self):
def get_t(t):
return t * t
b=1
k=self.get_t(b)
With regards to naming, get_xxx is usually a code smell in python. The get_ prefix indicates that the method is likely a getter, and pythonic code usually don't use getters/setters, because the language supports property. What you have on here though, isn't actually a getter but rather a computation method, so it shouldn't be prefixed with get_. A better name might be calculate_t(t) or square(t).
Case 1: If self is there:-
class example:
def get_t(self,t):
return t*t
Then You can not access get_t function directly from class example like example.get_t(t=2) ,it will give you error. But you can access now by creating an object of class like q = example() and then q.get_t(t=2) , it will give you your desired result.
Case 2 : If self is not there:-
class example:
def get_t(t):
return t*t
Now You can directly access get_t function by class example like example.get_t(t=2) ,it will give you your desired result. But now you cannot use get_t function by creating object like q = example() then q.get_t(t=2) it will give you error.
Conclusion :- It all depends on your use case. But when you struck in this type of ambiguity use #staticmethod like given below:-
class example:
#staticmethod
def get_t(t):
return t*t
I hope it may help you.
Say I have a class
class Base(object):
def my_method(self, input):
print input #suppose this is many lines
print "mymethod" #so is this
and a subclass that has a method which does almost the same thing, except for an extra operation in the middle of the method, e.g.
class Sub(Base):
def mymethod(self, input): #how do I properly define this?
print input
print "some other stuff" #additional operation in the middle
print "mymethod"
What is the proper way to overriding mymethod?
Do I copy-and-paste the majority of Base.mymethod()? (Probably not - that definitely violates DRY).
Do I define Base.mymethod() to have a conditional statement for the additional operation that only returns true in a subclass case? (Probably not - that doesn't make sense since the base class should be standalone and this seems like a recipe for disaster)
Can I somehow use super()? (Seems not - Sub's additional operation is in the middle of the method, not the beginning or end)
For such a simple example, I will most likely copy these three small lines, even if creates a repetitions. Try to avoid over-engineering.
In the case where my_method() is actually more complex, you can divide your function into three steps, and let the child classes overload the part they want.
class Base(object):
def my_method(self, input):
self._preprocess(input)
self._process()
self._postprocess()
def _preprocess(self, input):
print(input)
def _process(self):
pass
def _postprocess(self):
print("mymethod")
class Sub(Base):
def _process(self):
print("some other stuff")
Of course you should use more meaningful method names.
That depends on where stuff belongs. Usually if you end up wanting to insert stuff in between operations of the base's method, it means that method should actually be split into several methods.
For instance:
class Base(object):
def my_method(self, input):
print input #suppose this is many lines
print "mymethod" #so is this
could become:
class Base(object):
def my_method(self, input):
self.do_first_thing(input)
self.do_second_thing("mymethod")
def do_first_thing(self, input):
print(input)
def do_second_thing(self, data):
print(data)
This lets subclasses redefine the whole process without having to re-implement each step. The concept is akin to a template method, but backwards.
(Normally the point of a template method pattern is to let subclasses redefine steps, here we use the same structure to let subclasses redefine the template itself).
I'm sure this is well understood, but even the examples I see I have trouble understanding how to use functions defined within a particular class.
The simple example I've made is as follows (make a function add_one that adds 1 to a given input number and then use that function in another function add_two):
class TestPassingFunctions:
def __init__(self, number):
self.number = number
def add_one(self, number):
return number + 1
def add_two(self, number):
new_value = self.add_one(number) + 1
return new_value
TestPassingFunctions.add_two(2)
This returns:
TypeError: add_two() missing 1 required positional argument: 'number'
From what I've read, it looks the class is interpreting the 2 as the self parameter. As is probably obvious, I don't entirely understand when/how I should be using the initialization with __init__. Up until this point, I thought it should be used to propagate variable values through the class to be used by the different functions, but there's clearly some flaw in my use.
Thanks for any help!
You need to initialize an object of type TestPassingFunctions. Do this like so:
test = TestPassingFunctions(1)
test.add_two(2)
You need to generate an instance of the class first:
a = TestPassingFunctions(1)
print(a.add_two(2))
If you don't want to always create an instance, you can make the function a classmethod or a staticmethod (useful if you want classes for inheritance but not specifically to hold state (local variables associated with each instance))
class TestPassingFunctions:
#staticmethod #doesn't need anything else from the class
def add_one(number):
return number + 1
#classmethod #may need to refer to the class (in this case to access cls.add_one)
def add_two(cls, number):
new_value = cls.add_one(number) + 1
return new_value
TestPassingFunctions.add_two(2) #returns 4
Here's a quick guide on the different types of methods you can use
You are mixing the contents of class methods, static methods and regular methods of a class.
These methods are defined to be used as regular methods, with an instance of your class:
test = TestPassingFunctions(1)
test.add_two
If you want to call them without an instance, like TestPassingFunctions.add_two(2), you should define them as static or class methods, with a decorator #staticmethod and without self as first parameter
I am using the decorator design pattern to build a "composite class" that composes together the behavior of a set of "component classes". The behavior of the relevant method from each component class is governed by a dictionary param_dict, so that each component class has its own param_dict. The composite class also has a composite_param_dict, which is successively built up from the component dictionaries.
The behavior I need is the following: when an instance of the composite class has a value of composite_param_dict changed, I need the behavior of the inherited method to change.
Here is a minimal example of my class design:
class Component(object):
def __init__(self):
self.param_dict = {'a':4}
def component_method(self, x):
return self.param_dict['a']*x
I pass an instance of Component to the Composite constructor:
class Composite(object):
def __init__(self, instance):
self.instance = instance
# In the following line of code,
# I use copy to emphasize that there actually multiple
# instance.param_dict that are being passed to init,
# so composite_param_dict is not simply a reference
self.composite_param_dict = copy(self.instance.param_dict)
setattr(self, 'composite_method', self.param_dict_decorator(getattr(self.instance, 'component_method')))
def param_dict_decorator(self, func):
self.instance.param_dict['a'] = self.composite_param_dict['a']
return func
For the sake of being concise in this example, there is only one component, but in general there are many, so in general composite_param_dict has many keys, and the composite class has many inherited methods.
Additionally, I need to use getattr and setattr because I will not necessarily know in advance what the names of the methods I will need to inherit are. In general, the component models will tell the composite model which methods to inherit, so I cannot hard-code the method names into the composite model. In this minimal example, for the sake of being concise, I have gone ahead and hard-coded the method name component_method, and suppressed the mechanism by which this information is transmitted.
I build my composite class as follows:
component_instance = Component()
composite_instance = Composite(component_instance)
With my decorator written as I have in the above example, changes in the composite_param_dict do not propagate correctly, but I do not understand why not. For example:
composite_instance.composite_param_dict['a'] = 10
print composite_instance.composite_method(10)
40
If the values of composite_param_dict were correctly propagating, then the correct answer should be 100.
You only call param_dict_decorator once, at the moment when you create the composite_method. It is not called again every time you call the composite method. So it effectively "freezes" self.instance.param_dict with the value present in self.composite_param_dict at the time when you create the composite object.
If you want custom code to run every time composite_method is called, you can't just return func from param_dict_decorator. param_dict_decorator is only called once; it is what is returned from param_dict_decorator that you assign to composite_method, so that is what will be called whenever you call composite_method. So you need param_dict_decorator to return a new function that incorporates the "updating" behavior. Here's an example:
def param_dict_decorator(self, func):
def wrapper(*args, **kw):
self.instance.param_dict['a'] = self.composite_param_dict['a']
return func(*args, **kw)
return wrapper
With this change, it works:
>>> composite_instance = Composite(component_instance)
>>> composite_instance.composite_method(10)
40
>>> composite_instance.composite_param_dict['a'] = 10
>>> composite_instance.composite_method(10)
100
More generally, the concept of decorators is that they take in a function and return a new function that is meant to replace the original function. In your param_dict_decorator, you just return the original function, so your decorator has no effect at all on the behavior of func.