Related
When I try to print an instance of a class, I get an output like this:
>>> class Test():
... def __init__(self):
... self.a = 'foo'
...
>>> print(Test())
<__main__.Test object at 0x7fc9a9e36d60>
How can I make it so that the print will show something custom (e.g. something that includes the a attribute value)? That is, how can I can define how the instances of the class will appear when printed (their string representation)?
See How can I choose a custom string representation for a class itself (not instances of the class)? if you want to define the behaviour for the class itself (in this case, so that print(Test) shows something custom, rather than <class __main__.Test> or similar). (In fact, the technique is essentially the same, but trickier to apply.)
>>> class Test:
... def __repr__(self):
... return "Test()"
... def __str__(self):
... return "member of Test"
...
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test
The __str__ method is what gets called happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt).
If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.
As Chris Lutz explains, this is defined by the __repr__ method in your class.
From the documentation of repr():
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.
Given the following class Test:
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return f"<Test a:{self.a} b:{self.b}>"
def __str__(self):
return f"From str method of Test: a is {self.a}, b is {self.b}"
..it will act the following way in the Python shell:
>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print(repr(t))
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456
If no __str__ method is defined, print(t) (or print(str(t))) will use the result of __repr__ instead
If no __repr__ method is defined then the default is used, which is roughly equivalent to:
def __repr__(self):
cls = self.__class__
return f"<{cls.__module_}.{cls.__qualname__} object at {id(self)}>"
If you're in a situation like #Keith you could try:
print(a.__dict__)
It goes against what I would consider good style but if you're just trying to debug then it should do what you want.
A generic way that can be applied to any class without specific formatting could be done as follows:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + ": " + str(self.__dict__)
And then,
elem = Element('my_name', 'some_symbol', 3)
print(elem)
produces
__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
A prettier version of response by #user394430
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))
elem = Element('my_name', 'some_symbol', 3)
print(elem)
Produces visually nice list of the names and values.
<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3
An even fancier version (thanks Ruud) sorts the items:
def __str__(self):
return str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
Simple. In the print, do:
print(foobar.__dict__)
as long as the constructor is
__init__
For Python 3:
If the specific format isn't important (e.g. for debugging) just inherit from the Printable class below. No need to write code for every object.
Inspired by this answer
class Printable:
def __repr__(self):
from pprint import pformat
return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)
# Example Usage
class MyClass(Printable):
pass
my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)
Just to add my two cents to #dbr's answer, following is an example of how to implement this sentence from the official documentation he's cited:
"[...] to return a string that would yield an object with the same value when passed to eval(), [...]"
Given this class definition:
class Test(object):
def __init__(self, a, b):
self._a = a
self._b = b
def __str__(self):
return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)
def __repr__(self):
return 'Test("%s","%s")' % (self._a, self._b)
Now, is easy to serialize instance of Test class:
x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print
y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print
So, running last piece of code, we'll get:
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
But, as I said in my last comment: more info is just here!
You need to use __repr__. This is a standard function like __init__.
For example:
class Foobar():
"""This will create Foobar type object."""
def __init__(self):
print "Foobar object is created."
def __repr__(self):
return "Type what do you want to see here."
a = Foobar()
print a
__repr__ and __str__ are already mentioned in many answers. I just want to add that if you are too lazy to add these magic functions to your class, you can use objprint. A simple decorator #add_objprint will help you add the __str__ method to your class and you can use print for the instance. Of course if you like, you can also use objprint function from the library to print any arbitrary objects in human readable format.
from objprint import add_objprint
class Position:
def __init__(self, x, y):
self.x = x
self.y = y
#add_objprint
class Player:
def __init__(self):
self.name = "Alice"
self.age = 18
self.items = ["axe", "armor"]
self.coins = {"gold": 1, "silver": 33, "bronze": 57}
self.position = Position(3, 5)
print(Player())
The output is like
<Player
.name = 'Alice',
.age = 18,
.items = ['axe', 'armor'],
.coins = {'gold': 1, 'silver': 33, 'bronze': 57},
.position = <Position
.x = 3,
.y = 5
>
>
There are already a lot of answers in this thread but none of them particularly helped me, I had to work it out myself, so I hope this one is a little more informative.
You just have to make sure you have parentheses at the end of your class, e.g:
print(class())
Here's an example of code from a project I was working on:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number
class Hydrogen(Element):
def __init__(self):
super().__init__(name = "Hydrogen", symbol = "H", number = "1")
To print my Hydrogen class, I used the following:
print(Hydrogen())
Please note, this will not work without the parentheses at the end of Hydrogen. They are necessary.
Hope this helps, let me know if you have anymore questions.
Even though this is an older post, there is also a very convenient method introduced in dataclasses (as of Python 3.7). Besides other special functions such as __eq__ and __hash__, it provides a __repr__ function for class attributes. You example would then be:
from dataclasses import dataclass, field
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar")
t = Test()
print(t)
# prints Test(a='foo', b='bar')
If you want to hide a certain attribute from being outputted, you can set the field decorator parameter repr to False:
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar", repr=False)
t = Test()
print(t)
# prints Test(a='foo')
When I try to print an instance of a class, I get an output like this:
>>> class Test():
... def __init__(self):
... self.a = 'foo'
...
>>> print(Test())
<__main__.Test object at 0x7fc9a9e36d60>
How can I make it so that the print will show something custom (e.g. something that includes the a attribute value)? That is, how can I can define how the instances of the class will appear when printed (their string representation)?
See How can I choose a custom string representation for a class itself (not instances of the class)? if you want to define the behaviour for the class itself (in this case, so that print(Test) shows something custom, rather than <class __main__.Test> or similar). (In fact, the technique is essentially the same, but trickier to apply.)
>>> class Test:
... def __repr__(self):
... return "Test()"
... def __str__(self):
... return "member of Test"
...
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test
The __str__ method is what gets called happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt).
If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.
As Chris Lutz explains, this is defined by the __repr__ method in your class.
From the documentation of repr():
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.
Given the following class Test:
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return f"<Test a:{self.a} b:{self.b}>"
def __str__(self):
return f"From str method of Test: a is {self.a}, b is {self.b}"
..it will act the following way in the Python shell:
>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print(repr(t))
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456
If no __str__ method is defined, print(t) (or print(str(t))) will use the result of __repr__ instead
If no __repr__ method is defined then the default is used, which is roughly equivalent to:
def __repr__(self):
cls = self.__class__
return f"<{cls.__module_}.{cls.__qualname__} object at {id(self)}>"
If you're in a situation like #Keith you could try:
print(a.__dict__)
It goes against what I would consider good style but if you're just trying to debug then it should do what you want.
A generic way that can be applied to any class without specific formatting could be done as follows:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + ": " + str(self.__dict__)
And then,
elem = Element('my_name', 'some_symbol', 3)
print(elem)
produces
__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
A prettier version of response by #user394430
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))
elem = Element('my_name', 'some_symbol', 3)
print(elem)
Produces visually nice list of the names and values.
<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3
An even fancier version (thanks Ruud) sorts the items:
def __str__(self):
return str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
Simple. In the print, do:
print(foobar.__dict__)
as long as the constructor is
__init__
For Python 3:
If the specific format isn't important (e.g. for debugging) just inherit from the Printable class below. No need to write code for every object.
Inspired by this answer
class Printable:
def __repr__(self):
from pprint import pformat
return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)
# Example Usage
class MyClass(Printable):
pass
my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)
Just to add my two cents to #dbr's answer, following is an example of how to implement this sentence from the official documentation he's cited:
"[...] to return a string that would yield an object with the same value when passed to eval(), [...]"
Given this class definition:
class Test(object):
def __init__(self, a, b):
self._a = a
self._b = b
def __str__(self):
return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)
def __repr__(self):
return 'Test("%s","%s")' % (self._a, self._b)
Now, is easy to serialize instance of Test class:
x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print
y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print
So, running last piece of code, we'll get:
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
But, as I said in my last comment: more info is just here!
You need to use __repr__. This is a standard function like __init__.
For example:
class Foobar():
"""This will create Foobar type object."""
def __init__(self):
print "Foobar object is created."
def __repr__(self):
return "Type what do you want to see here."
a = Foobar()
print a
__repr__ and __str__ are already mentioned in many answers. I just want to add that if you are too lazy to add these magic functions to your class, you can use objprint. A simple decorator #add_objprint will help you add the __str__ method to your class and you can use print for the instance. Of course if you like, you can also use objprint function from the library to print any arbitrary objects in human readable format.
from objprint import add_objprint
class Position:
def __init__(self, x, y):
self.x = x
self.y = y
#add_objprint
class Player:
def __init__(self):
self.name = "Alice"
self.age = 18
self.items = ["axe", "armor"]
self.coins = {"gold": 1, "silver": 33, "bronze": 57}
self.position = Position(3, 5)
print(Player())
The output is like
<Player
.name = 'Alice',
.age = 18,
.items = ['axe', 'armor'],
.coins = {'gold': 1, 'silver': 33, 'bronze': 57},
.position = <Position
.x = 3,
.y = 5
>
>
There are already a lot of answers in this thread but none of them particularly helped me, I had to work it out myself, so I hope this one is a little more informative.
You just have to make sure you have parentheses at the end of your class, e.g:
print(class())
Here's an example of code from a project I was working on:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number
class Hydrogen(Element):
def __init__(self):
super().__init__(name = "Hydrogen", symbol = "H", number = "1")
To print my Hydrogen class, I used the following:
print(Hydrogen())
Please note, this will not work without the parentheses at the end of Hydrogen. They are necessary.
Hope this helps, let me know if you have anymore questions.
Even though this is an older post, there is also a very convenient method introduced in dataclasses (as of Python 3.7). Besides other special functions such as __eq__ and __hash__, it provides a __repr__ function for class attributes. You example would then be:
from dataclasses import dataclass, field
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar")
t = Test()
print(t)
# prints Test(a='foo', b='bar')
If you want to hide a certain attribute from being outputted, you can set the field decorator parameter repr to False:
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar", repr=False)
t = Test()
print(t)
# prints Test(a='foo')
When I try to print an instance of a class, I get an output like this:
>>> class Test():
... def __init__(self):
... self.a = 'foo'
...
>>> print(Test())
<__main__.Test object at 0x7fc9a9e36d60>
How can I make it so that the print will show something custom (e.g. something that includes the a attribute value)? That is, how can I can define how the instances of the class will appear when printed (their string representation)?
See How can I choose a custom string representation for a class itself (not instances of the class)? if you want to define the behaviour for the class itself (in this case, so that print(Test) shows something custom, rather than <class __main__.Test> or similar). (In fact, the technique is essentially the same, but trickier to apply.)
>>> class Test:
... def __repr__(self):
... return "Test()"
... def __str__(self):
... return "member of Test"
...
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test
The __str__ method is what gets called happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt).
If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.
As Chris Lutz explains, this is defined by the __repr__ method in your class.
From the documentation of repr():
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.
Given the following class Test:
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return f"<Test a:{self.a} b:{self.b}>"
def __str__(self):
return f"From str method of Test: a is {self.a}, b is {self.b}"
..it will act the following way in the Python shell:
>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print(repr(t))
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456
If no __str__ method is defined, print(t) (or print(str(t))) will use the result of __repr__ instead
If no __repr__ method is defined then the default is used, which is roughly equivalent to:
def __repr__(self):
cls = self.__class__
return f"<{cls.__module_}.{cls.__qualname__} object at {id(self)}>"
If you're in a situation like #Keith you could try:
print(a.__dict__)
It goes against what I would consider good style but if you're just trying to debug then it should do what you want.
A generic way that can be applied to any class without specific formatting could be done as follows:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + ": " + str(self.__dict__)
And then,
elem = Element('my_name', 'some_symbol', 3)
print(elem)
produces
__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
A prettier version of response by #user394430
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))
elem = Element('my_name', 'some_symbol', 3)
print(elem)
Produces visually nice list of the names and values.
<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3
An even fancier version (thanks Ruud) sorts the items:
def __str__(self):
return str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
Simple. In the print, do:
print(foobar.__dict__)
as long as the constructor is
__init__
For Python 3:
If the specific format isn't important (e.g. for debugging) just inherit from the Printable class below. No need to write code for every object.
Inspired by this answer
class Printable:
def __repr__(self):
from pprint import pformat
return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)
# Example Usage
class MyClass(Printable):
pass
my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)
Just to add my two cents to #dbr's answer, following is an example of how to implement this sentence from the official documentation he's cited:
"[...] to return a string that would yield an object with the same value when passed to eval(), [...]"
Given this class definition:
class Test(object):
def __init__(self, a, b):
self._a = a
self._b = b
def __str__(self):
return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)
def __repr__(self):
return 'Test("%s","%s")' % (self._a, self._b)
Now, is easy to serialize instance of Test class:
x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print
y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print
So, running last piece of code, we'll get:
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
Human readable: An instance of class Test with state: a=hello b=world
Object representation: Test("hello","world")
But, as I said in my last comment: more info is just here!
You need to use __repr__. This is a standard function like __init__.
For example:
class Foobar():
"""This will create Foobar type object."""
def __init__(self):
print "Foobar object is created."
def __repr__(self):
return "Type what do you want to see here."
a = Foobar()
print a
__repr__ and __str__ are already mentioned in many answers. I just want to add that if you are too lazy to add these magic functions to your class, you can use objprint. A simple decorator #add_objprint will help you add the __str__ method to your class and you can use print for the instance. Of course if you like, you can also use objprint function from the library to print any arbitrary objects in human readable format.
from objprint import add_objprint
class Position:
def __init__(self, x, y):
self.x = x
self.y = y
#add_objprint
class Player:
def __init__(self):
self.name = "Alice"
self.age = 18
self.items = ["axe", "armor"]
self.coins = {"gold": 1, "silver": 33, "bronze": 57}
self.position = Position(3, 5)
print(Player())
The output is like
<Player
.name = 'Alice',
.age = 18,
.items = ['axe', 'armor'],
.coins = {'gold': 1, 'silver': 33, 'bronze': 57},
.position = <Position
.x = 3,
.y = 5
>
>
There are already a lot of answers in this thread but none of them particularly helped me, I had to work it out myself, so I hope this one is a little more informative.
You just have to make sure you have parentheses at the end of your class, e.g:
print(class())
Here's an example of code from a project I was working on:
class Element:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number
class Hydrogen(Element):
def __init__(self):
super().__init__(name = "Hydrogen", symbol = "H", number = "1")
To print my Hydrogen class, I used the following:
print(Hydrogen())
Please note, this will not work without the parentheses at the end of Hydrogen. They are necessary.
Hope this helps, let me know if you have anymore questions.
Even though this is an older post, there is also a very convenient method introduced in dataclasses (as of Python 3.7). Besides other special functions such as __eq__ and __hash__, it provides a __repr__ function for class attributes. You example would then be:
from dataclasses import dataclass, field
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar")
t = Test()
print(t)
# prints Test(a='foo', b='bar')
If you want to hide a certain attribute from being outputted, you can set the field decorator parameter repr to False:
#dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar", repr=False)
t = Test()
print(t)
# prints Test(a='foo')
Apologies for incorrect lingo, I am still new to this.
I want to make a class initialiser that, using a conditional, will decide whether or not the instance of said class will collapse into a simple integer.
Simplified Unworking Example:
class A(object):
def __init__(self,a,b):
self.a = a
self.b = b
if self.b == 0:
return int(a)
def __repr__(self):
return str(a)+":"+str(b)
DoesntBecomeAnInt = A(3,4)
WillBecomeAnInt = A(3,0)
print(DoesntBecomeAnInt,WillBecomeAnInt)
##Desired Output:
##3:4, 3
Any help would be very much appreciated!
You should use the magic method __new__ for this. __new__ is used as a factory where you can decide which class should be instantiated.
class A(object):
def __new__(self, a):
return int(a)
A(4)
> 4
A(4).__class__
> <type 'int'>
class A:
def __new__(cls, a, b):
if b == 0:
return a
return super().__new__(cls)
def __init__(self, a, b):
print('Initilizing')
self.a = a
self.b = b
def __repr__(self):
return str(self.a)+":"+str(self.b)
__new__ is the method used to control the creation of new objects (hence the name). Here we check if b is zero in __new__ and return an instance of the appropriate type.
In action:
>>> DoesntBecomeAnInt = A(3,4)
Initilizing
>>> WillBecomeAnInt = A(3,0)
>>> print(DoesntBecomeAnInt,WillBecomeAnInt)
3:4 3
You don't.
The behavior you desire is completely unexpected and somewhat bizarre. Calling A() is expected to return an instance of A. Doing anything else is confusing and unintuitive, which makes it difficult to read and understand any code invoking it.
Alternative
If you really need this behavior, create a factory method:
def make_thing(a, b):
if 0 == b:
return int(a)
else:
return A(a, b)
Obviously, you need a better name than make_thing, but without any context, I can't give you any suggestions.
Avoid the problem if possible
Since A is not a number and is generally not compatible with int, it is also somewhat strange to store both int and A in the same variable.
If all you're doing is converting to a string, then you don't need a class at all. A simple method outside of a class is the better alternative:
def a_and_b_to_string(a, b):
if b == 0:
return str(int(a))
else:
return str(a) + ":" + str(b)
If you're doing more than that, your calling code will probably end up looking something like this:
x = make_thing(input1, input2)
if isinstance(x, A):
result = x.some_method_from_a() # Or some other calculation requiring an A
else:
result = 5 * x # Or some other calculation requiring an `int`
This is somewhat silly: you write a method to choose the data type and then have to write specialized code for each possible result. You're not getting any benefits from having a function that returns the separate types here. I can think of two simpler alternatives:
Just move the check to the calling code:
if input2 == 0:
temp = A(input1, input2)
result = temp.some_method_from_a() # Or some other calculation requiring an A
else:
result = 5 * int(input1) # Or some other calculation requiring an int
If you go this route, you should also modify A.__init__ to throw a ValueError if b == 0, since that would be an invalid state for an A to be in.
Modify A so that it works properly regardless of whether b is 0:
class A(object):
def __init__(self,a,b):
self.a = a
self.b = b
def some_method_from_a():
if self.b == 0:
# Some calculation involving only a
return int(self.a) * 5
else:
# Some other more complex calculation involving both a and b
return self.a * self.b * 6
def __repr__(self):
if self.b == 0:
return str(int(self.a))
else:
return str(self.a) + ":" + str(self.b)
Then
x = A(a, b)
result = x.some_method_from_a()
But again, it's hard to provide recommendations without knowing how you're actually using it.
Using dataclasses
# A(...) should either raise an exception or
# return an instance of A to avoid confusion.
# create can do whatever you want it to.
import dataclasses
#dataclasses.dataclass
class A:
print('Initializing')
a : int
b : int
def __repr__(self):
if self.b == 0:
return str(int(self.a))
else:
return str(self.a) + ":" + str(self.b)
#classmethod
def create(cls, a, b):
if b == 0:
return a
return cls(a, b)
DoesntBecomeAnInt = A.create(3,4)
WillBecomeAnInt = A.create(3,0)
print(f'{DoesntBecomeAnInt}\n{WillBecomeAnInt}')
Initializing
3:4
3
[Program finished]
I'm trying to create a class that returns a value, not self.
I will show you an example comparing with a list:
>>> l = list()
>>> print(l)
[]
>>> class MyClass:
>>> pass
>>> mc = MyClass()
>>> print mc
<__main__.MyClass instance at 0x02892508>
I need that MyClass returns a list, like list() does, not the instance info. I know that I can make a subclass of list. But is there a way to do it without subclassing?
I want to imitate a list (or other objects):
>>> l1 = list()
>>> l2 = list()
>>> l1
[]
>>> l2
[]
>>> l1 == l2
True
>>> class MyClass():
def __repr__(self):
return '[]'
>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1
[]
>>> m2
[]
>>> m1 == m2
False
Why is m1 == m2 False? This is the question.
I'm sorry if I don't respond to all of you. I'm trying all the solutions you give me. I cant use def, because I need to use functions like setitem, getitem, etc.
I think you are very confused about what is occurring.
In Python, everything is an object:
[] (a list) is an object
'abcde' (a string) is an object
1 (an integer) is an object
MyClass() (an instance) is an object
MyClass (a class) is also an object
list (a type--much like a class) is also an object
They are all "values" in the sense that they are a thing and not a name which refers to a thing. (Variables are names which refer to values.) A value is not something different from an object in Python.
When you call a class object (like MyClass() or list()), it returns an instance of that class. (list is really a type and not a class, but I am simplifying a bit here.)
When you print an object (i.e. get a string representation of an object), that object's __str__ or __repr__ magic method is called and the returned value printed.
For example:
>>> class MyClass(object):
... def __str__(self):
... return "MyClass([])"
... def __repr__(self):
... return "I am an instance of MyClass at address "+hex(id(self))
...
>>> m = MyClass()
>>> print m
MyClass([])
>>> m
I am an instance of MyClass at address 0x108ed5a10
>>>
So what you are asking for, "I need that MyClass return a list, like list(), not the instance info," does not make any sense. list() returns a list instance. MyClass() returns a MyClass instance. If you want a list instance, just get a list instance. If the issue instead is what do these objects look like when you print them or look at them in the console, then create a __str__ and __repr__ method which represents them as you want them to be represented.
Update for new question about equality
Once again, __str__ and __repr__ are only for printing, and do not affect the object in any other way. Just because two objects have the same __repr__ value does not mean they are equal!
MyClass() != MyClass() because your class does not define how these would be equal, so it falls back to the default behavior (of the object type), which is that objects are only equal to themselves:
>>> m = MyClass()
>>> m1 = m
>>> m2 = m
>>> m1 == m2
True
>>> m3 = MyClass()
>>> m1 == m3
False
If you want to change this, use one of the comparison magic methods
For example, you can have an object that is equal to everything:
>>> class MyClass(object):
... def __eq__(self, other):
... return True
...
>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1 == m2
True
>>> m1 == m1
True
>>> m1 == 1
True
>>> m1 == None
True
>>> m1 == []
True
I think you should do two things:
Take a look at this guide to magic method use in Python.
Justify why you are not subclassing list if what you want is very list-like. If subclassing is not appropriate, you can delegate to a wrapped list instance instead:
class MyClass(object):
def __init__(self):
self._list = []
def __getattr__(self, name):
return getattr(self._list, name)
# __repr__ and __str__ methods are automatically created
# for every class, so if we want to delegate these we must
# do so explicitly
def __repr__(self):
return "MyClass(%s)" % repr(self._list)
def __str__(self):
return "MyClass(%s)" % str(self._list)
This will now act like a list without being a list (i.e., without subclassing list).
>>> c = MyClass()
>>> c.append(1)
>>> c
MyClass([1])
If what you want is a way to turn your class into kind of a list without subclassing list, then just make a method that returns a list:
def MyClass():
def __init__(self):
self.value1 = 1
self.value2 = 2
def get_list(self):
return [self.value1, self.value2...]
>>>print MyClass().get_list()
[1, 2...]
If you meant that print MyClass() will print a list, just override __repr__:
class MyClass():
def __init__(self):
self.value1 = 1
self.value2 = 2
def __repr__(self):
return repr([self.value1, self.value2])
EDIT:
I see you meant how to make objects compare. For that, you override the __cmp__ method.
class MyClass():
def __cmp__(self, other):
return cmp(self.get_list(), other.get_list())
Use __new__ to return value from a class.
As others suggest __repr__,__str__ or even __init__ (somehow) CAN give you what you want, But __new__ will be a semantically better solution for your purpose since you want the actual object to be returned and not just the string representation of it.
Read this answer for more insights into __str__ and __repr__
https://stackoverflow.com/a/19331543/4985585
class MyClass():
def __new__(cls):
return list() #or anything you want
>>> MyClass()
[] #Returns a true list not a repr or string
class MyClass():
def __init__(self, a, b):
self.value1 = a
self.value2 = b
def __call__(self):
return [self.value1, self.value2]
Testing:
>>> x = MyClass('foo','bar')
>>> x()
['foo', 'bar']
You are describing a function, not a class.
def Myclass():
return []
the worked proposition for me is __call__ on class who create list of little numbers:
import itertools
class SmallNumbers:
def __init__(self, how_much):
self.how_much = int(how_much)
self.work_list = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉']
self.generated_list = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉']
start = 10
end = 100
for cmb in range(2, len(str(self.how_much)) + 1):
self.ListOfCombinations(is_upper_then=start, is_under_then=end, combinations=cmb)
start *= 10
end *= 10
def __call__(self, number, *args, **kwargs):
return self.generated_list[number]
def ListOfCombinations(self, is_upper_then, is_under_then, combinations):
multi_work_list = eval(str('self.work_list,') * combinations)
nbr = 0
for subset in itertools.product(*multi_work_list):
if is_upper_then <= nbr < is_under_then:
self.generated_list.append(''.join(subset))
if self.how_much == nbr:
break
nbr += 1
and to run it:
if __name__ == '__main__':
sm = SmallNumbers(56)
print(sm.generated_list)
print(sm.generated_list[34], sm.generated_list[27], sm.generated_list[10])
print('The Best', sm(15), sm(55), sm(49), sm(0))
result
['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉', '₁₀', '₁₁', '₁₂', '₁₃', '₁₄', '₁₅', '₁₆', '₁₇', '₁₈', '₁₉', '₂₀', '₂₁', '₂₂', '₂₃', '₂₄', '₂₅', '₂₆', '₂₇', '₂₈', '₂₉', '₃₀', '₃₁', '₃₂', '₃₃', '₃₄', '₃₅', '₃₆', '₃₇', '₃₈', '₃₉', '₄₀', '₄₁', '₄₂', '₄₃', '₄₄', '₄₅', '₄₆', '₄₇', '₄₈', '₄₉', '₅₀', '₅₁', '₅₂', '₅₃', '₅₄', '₅₅', '₅₆']
₃₄ ₂₇ ₁₀
The Best ₁₅ ₅₅ ₄₉ ₀