- How to return a value from __init__ in Python?
- 13 Answers 13
- init() return none value solved perfectly
- Adding return type to init function python
- Return type for __init__ in docstrings
- Why does Init function return Object type but other functions return the NoneType
- How to not have to type self in init when subclassing
- How to reflect Base’s class __init__ parameters (with docs string / type hints etc) through Child Class __Init__
- putting current class as return type annotation [duplicate]
- 2 Answers 2
How to return a value from __init__ in Python?
I have a class with an __init__ function. How can I return an integer value from this function when an object is created? I wrote a program, where __init__ does command line parsing and I need to have some value set. Is it OK set it in global variable and use it in other member functions? If so how to do that? So far, I declared a variable outside class. and setting it one function doesn’t reflect in other function ??
Please remove your comment and update your question. You own the question. It’s your question. Please fix the question to correctly show what your real problem is. You’re misusing __init__ ; we can help you if you describe what you’re really trying to accomplish.
__init__ probably should not be doing command-line parsing. Define a class method that does the actual parsing, and pass the parsed values to __init__ . Let __init__ worry about creating the necessary attributes, not figuring out how to produce the values for those attributes.
Note for future readers: If you want to get generic information back as a result of calling __init__ , see the answers given here. If you want to signal that something went wrong, raise an exception. That doesn’t answer the question that was asked here, but might be what you have in mind.
13 Answers 13
If you want to return some other object when a class is called, then use the __new__() method:
class MyClass: def __init__(self): print("never called in this case") def __new__(cls): return 42 obj = MyClass() print(obj) # Output: 42
Yeah, new is the right way of returning something other than a class instance when using a class. I’m just wondering — is there any reason you might actually want to DO that?
@weronika One idea: in any situation where you’d normally use a factory, but you have some reason to want to present an interface that looks like normal class instantiation. Example: when adding some new optional parameters into your class’s __init__ , you realise that really, to provide the flexibility you want, you need a class factory that returns instances of specialised subclasses. But your library’s users are already using your existing API. To preserve it, you override __new__ to return instances of your specialised subclasses.
If you want to see an example of what Mark Amery said, check out the source code of the datetime module from the Standard Library. It uses __new__ in exactly this fashion.
I kind of think at this pount, just using a regular function makes more sense. Might be a bit alien to folks from the Java dimension (functions not in classes? heresy!) but its pythonic. (Also you can assign properties to functions as in funtionName.val =.. which is kind of wild but it works)
__init__ is required to return None. You cannot (or at least shouldn’t) return something else.
Try making whatever you want to return an instance variable (or function).
>>> class Foo: . def __init__(self): . return 42 . >>> foo = Foo() Traceback (most recent call last): File "", line 1, in TypeError: __init__() should return None
init doesn’t return the newly created object — as seen in the TypeError, it is required to return None, right? The newly created object is returned by new, init just sets some of its attributes. But yes, as you said, changing init, or new, to return something else really makes no sense.
Where is new here? Is new implicit in Python? I assumed Python’s semantics were different from Java and the other languages that do use this word.
Just because it can’t be done doesn’t mean it doesn’t make sense. It would, for instance, be nice to pass data from super().__init__ to the derived class without having to relay it through an instance variable.
As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime.
class Foo(object): def __init__(self): return 2 f = Foo()
Traceback (most recent call last): File "test_init.py", line 5, in f = Foo() TypeError: __init__() should return None, not 'int'
Sample Usage of the matter in question can be like:
class SampleObject(object): def __new__(cls, item): if cls.IsValid(item): return super(SampleObject, cls).__new__(cls) else: return None def __init__(self, item): self.InitData(item) #large amount of data and very complex calculations . ValidObjects = [] for i in data: item = SampleObject(i) if item: # in case the i data is valid for the sample object ValidObjects.append(item)
The __init__ method, like other methods and functions returns None by default in the absence of a return statement, so you can write it like either of these:
class Foo: def __init__(self): self.value=42 class Bar: def __init__(self): self.value=42 return None
But, of course, adding the return None doesn’t buy you anything.
I’m not sure what you are after, but you might be interested in one of these:
class Foo: def __init__(self): self.value=42 def __str__(self): return str(self.value) f=Foo() print f.value print f
@JLT Yes, you cam always do that but it still does not mean that anything is returned from __init__ .
__init__ doesn’t return anything and should always return None .
You can just set it to a class variable and read it from the main program:
class Foo: def __init__(self): #Do your stuff here self.returncode = 42 bar = Foo() baz = bar.returncode
We can not return value from init. But we can return value using new.
class Car: def __new__(cls, speed, unit): return (f" with unit ") car = Car(42, "km") print(car)
Yes, but you can’t really return arbitrary values from __new__ and still have the class «protocol» make sense.
init() return none value solved perfectly
class Solve: def __init__(self,w,d): self.value=w self.unit=d def __str__(self): return str("my speed is "+str(self.value)+" "+str(self.unit)) ob=Solve(21,'kmh') print (ob)
output: my speed is 21 kmh
Just wanted to add, you can return classes in __init__
@property def failureException(self): class MyCustomException(AssertionError): def __init__(self_, *args, **kwargs): *** Your code here *** return super().__init__(*args, **kwargs) MyCustomException.__name__ = AssertionError.__name__ return MyCustomException
The above method helps you implement a specific action upon an Exception in your test
Met this case when tried to parse some string data into a recursive data structure, and had a counter to be passed through.
Python does not allow to return anything from __init__ , but you may write a factory function, or a class method, or a Parser class, depending on the code structure and complexity of parsing, which will parse your data into data objects.
Global variable is not a good solution, as it may be changed somewhere else, breaking the parsing logic.
class MyClass(): def __init__(self, a, b, c): # only assignments here self.a = a self.b = b self.c = c # return None def parse(data): # parsing here a = . b = . c = . # status, counter, etc. i = . # create an object my_obj = MyClass(a, b, c) # return both return my_obj, i # get data and parse data = . my_obj, i = parse(data)
class MyClass(): def __init__(self, a, b, c): self.a = a self.b = b self.c = c @classmethod def parse(cls, data): a = . b = . c = . i = . obj = cls(a, b, c) return obj, i data = . my_obj, i = MyClass.parse(data)
Adding return type to init function python
Solution 1: If you are not changing any arguments in child class and they are the same as the parent class then there is no need to call in child class. When you crate a child class it takes all arguments from parent class.
Return type for __init__ in docstrings
(The answer to the question credit should go to @ppperry)
Because all __init__ methods return None , no docstrings about return type are required.
The __init__ method should return None . If you try to return anything else, Python will raise an error when the object is instantiated. Note: If you don’t explicitly tell Python what a function should return, it returns None. Because of this, I have never needed to use the return statement in any of my __init__ methods.
How to reflect Base’s class __init__ parameters (with docs string, If you want some arguments from parent class and you want to add more arguments then you need to use super().__init__(parent_arg1,
Why does Init function return Object type but other functions return the NoneType
If you want a fluid interface like that, your methods (other than __init__ ) need to return self .
class predictionsGrader(): def __init__(self, predictions, target): self.correct = [] self.predictions = predictions self.target = target def merge_on(self, row): self.row = row self.md = pd.merge(self.predictions, self.target, on=[self.row]) return self def compare(self, predicted_target, confirmed_target): self.predicted_target = predicted_target or "predicted_target" self.confirmed_target = confirmed_target or "confirmed_target" return self def grade(self): for x in range(len(self.md[self.predicted_target])): if (self.md[self.predicted_target][x] == self.md[self.confirmed_target][x]): self.correct.append("right") else: self.correct.append("wrong") return self.correct
__init__ shouldn’t return anything — it’s an initializer, not a constructor.
predictionsGrader() is not same as predictionsGrader.__init__() . __init__() is called as part of the initiation process by some Python magic in the background.
Class — __new__ and __init__ in Python, __new__ is good for immutable object as they cannot be changed once they are assigned. So we can return new instance which has new state. We can
How to not have to type self in init when subclassing
You need to annotate the return type of your signature:
class Foo: def __init__(self) -> None: pass
Mypy will let you omit the return type on specifically the constructor if one or more other arguments are annotated, but you’ll need to include it on no-argument constructors.
What does __init__ method return in python, __init__() returns None . It is __new__() that returns the new instance.
How to reflect Base’s class __init__ parameters (with docs string / type hints etc) through Child Class __Init__
If you are not changing any arguments in child class and they are the same as the parent class then there is no need to call __init__() in child class. When you crate a child class it takes all arguments from parent class. If you want some arguments from parent class and you want to add more arguments then you need to use super().__init__(parent_arg1, parent_arg2) . And when you create an object of your child class, it also has all methods from both child and parent class. Btw in your child class __init__() you can’t put str: arg it must be arg: str .
Based on the comment of @jfaccioni, I resolved it by not implementing init inside the child class. Now when I instantiate the child class, it behaves like as if I am instantiating Base class.
# base class class BaseClass: def __init__(self, base_arg1:str,base_arg2:str): "this is our base class" self.base_arg1 = base_arg1 self.base_arg2 = base_arg2 print("running base") # child class ChildClass(BaseClass): def some_other_fun(arg): self.arg = arg return None
Pandas — Run and return value of class function inside __init, All you need to so is call getDF like any other method, using self as the object on which it should be invoked. self.df_raw = self.
putting current class as return type annotation [duplicate]
The problem is I can’t make an annotation with return type of the current class (Graph), which is not defined yet. Example:
class Graph: def reverse(self) -> Graph: pass
def reverse(self) -> Graph: NameError: name 'Graph' is not defined
These annotations are really useful both for documenting and allowing IDE to recognize argument and return types => enable autocomplete UPD: So what I came up is this is either impossible or requires some hacks I don’t like, so I decided to use just def reverse (self) -> ‘Graph’: which is understandable for documentation although breaks the rule. The downside is that it doesn’t work for IDE autocomplete.
2 Answers 2
In python-3.7 this issue has been resolved by not evaluating the annotations at function definition time. Instead, they are preserved in __annotations__ in string form. This is called Postponed Evaluation of Annotations, introduced in PEP 563.
Deprecation policy
Starting with Python 3.7, a __future__ import is required to use the described functionality. No warnings are raised.
In Python 3.8 a PendingDeprecationWarning is raised by the compiler in the presence of type annotations in modules without the __future__ import.
Starting with Python 3.9 the warning becomes a DeprecationWarning .
In Python 4.0 this will become the default behavior. Use of annotations incompatible with this PEP is no longer supported.
In [7]: from __future__ import annotations In [8]: class C: . def func(cls, arg:str) -> C: . pass . In [9]: c = C()