what is means reconstruct object or recreate object in python? - python

I am trying to understand difference between __str__ and __repr__ and following Difference between __str__ and __repr__ in Python
In the answer it says __repr__'s goal is to be unambiguous, I am confused what that really means. Another answer says: __repr__: representation of python object usually eval will convert it back to that object, so I have read that eval function let execute the python code in it.
Can someone please explain these terms in simple language:
What is object reconstruction?
What is __repr__?
What is the connection between eval and __repr__?

Perhaps a simple example will help clarify:
class Object:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return 'Object({0.a!r}, {0.b!r})'.format(self)
This object has two parameters defined in __init__ and a sensible __repr__ method.
>>> o = Object(1, 2)
>>> repr(o)
'Object(1, 2)'
Note that the __repr__ of our object now looks exactly like how we created it to begin with; it's legal Python code that supplies the same values. As the data model documentation puts it:
If at all possible, [__repr__] should look like a valid Python
expression that could be used to recreate an object with the same
value (given an appropriate environment).
That's where eval comes in:
>>> x = eval(repr(o))
>>> x.a
1
>>> x.b
2
Because the representation is Python code, we can evalulate it and get an object with the same values. This is "reconstructing" the original object o.
However, as pointed out in the comments, this is just an illustration and doesn't mean that you should rely on repr(eval(x)) when trying to create a copy of x.

Related

How to call and print an item from another python file [duplicate]

This question already has answers here:
How to print instances of a class using print()?
(12 answers)
Closed 4 years ago.
In Java, I can override the toString() method of my class. Then Java's print function prints the string representation of the object defined by its toString(). Is there a Python equivalent to Java's toString()?
For example, I have a PlayCard class. I have an instance c of PlayCard. Now:
>>> print(c)
<__main__.Card object at 0x01FD5D30>
But what I want is something like:
>>> print(c)
A♣
How do I customize the string representation of my class instances?
I'm using Python 3.x
The closest equivalent to Java's toString is to implement __str__ for your class. Put this in your class definition:
def __str__(self):
return "foo"
You may also want to implement __repr__ to aid in debugging.
See here for more information:
Special Method Names - Basic Customization
This is not as easy as it seems, some core library functions don't work when only str is overwritten (checked with Python 2.7), see this thread for examples
How to make a class JSON serializable
Also, try this
import json
class A(unicode):
def __str__(self):
return 'a'
def __unicode__(self):
return u'a'
def __repr__(self):
return 'a'
a = A()
json.dumps(a)
produces
'""'
and not
'"a"'
as would be expected.
EDIT: answering mchicago's comment:
unicode does not have any attributes -- it is an immutable string, the value of which is hidden and not available from high-level Python code. The json module uses re for generating the string representation which seems to have access to this internal attribute. Here's a simple example to justify this:
b = A('b')
print b
produces
'a'
while
json.dumps({'b': b})
produces
{"b": "b"}
so you see that the internal representation is used by some native libraries, probably for performance reasons.
See also this for more details: http://www.laurentluce.com/posts/python-string-objects-implementation/

Python: Re-bind function as int

I have a test class:
class TestClass:
def someFunction(self, someInt):
self.i = someInt
return self.i
And was testing it with:
x = MyClass()
x.someFunction = 3
print(x.someFunction)
x.someFunction(4)
However, this leads to TypeError: 'int' object is not callable. I understand why I am getting this error--someFunction has been rebound to an integer (in this case, 3) and, well, an integer is not a function and therefore someFunction is no longer callable. But I am wondering what the reasoning is behind allowing a member function to be rebound just as if it is a data member? It seems prone to accidental errors. I am just starting to learn Python and feel like I'm missing a fundamental aspect of Python that this behavior would fit into.
This is allowed because of the way attribute lookup works in Python and this is by design. In Python, many things that are discouraged, forbidden or impossible in other languages, are allowed to leverage your use case (if used wisely). Of course, more power implies more responsibility.
After all, we're all consenting adults here.
Some background information on attribute resolution
Class instances start with an empty __dict__ attribute where all object attributes are stored. By accessing x.someFunction you are implicitly trying x.__dict__['someFunction']. If 'someFunction' does not exist in x.__dict__, the same is tried for the class of x, i.e. type(x).someFunction or better type(x).__dict__['someFunction'].
When your write x by doing x.someFunction = 3, what actually happens is x.__dict__['someFunction'] = 3, regardless of what the reading attribute access might return.
The only real (?) magic happens during method calls, where self is provided automatically, i.e. x.someFunction(4) is resolved to type(x).__dict__['someFunction'](x, 4) instead of type(x).__dict__['someFunction'](4) or x.__dict__['someFunction'](4). This is somewhat related to attribute access and may cause confusion.
So, you actually do not "rebind" the function, but hide the class attribute someFunction with the instance attribute someFunction of x. If you do
print(MyClass.someFunction)
print(MyClass().someFunction)
you will see that the method is still there. You can even restore the initial state with
del x.__dict__['someFunction']
Note: The things I described as resolution illustrate the concept. In reality the inner workings of python may be more subtle or complex, but they will have the same effect. For example, in Python 2, methods have been wrapped as so called unbound methods before being stored in the class dictionary. This has been dropped in Python 3, where the class dictionary contains the plain function.
Please execute your demo code in a python shell:
>>> class TestClass:
... def someFunction(self, someInt):
... self.i = someInt
... return self.i
...
>>> x = TestClass()
>>> x.someFunction = 3
>>> print(x.someFunction)
3
>>> x.someFunction(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Please see the following content:
>>> type(x.someFunction)
<type 'instancemethod'>
>>> x.someFunction = 3
>>> type(x.someFunction)
<type 'int'>
If you try x.someFunction = 3, the instancemethod caled x.someFunction translates into a int.
In python
functions are threated as first-class objects
and variables are not typed.
Or just "Everything is an object" in python. So there is just no fundamental difference of a variable containing an integer vs a variable containing a function. Both, first-class functions and untyped variables have it's own pros and cons but allow you to e.g. simply make a list that contains integers, string, other objects as well as functions.
The reason you can assign anything to function variables is because they are implemented as objects. This enables you to return functions and pass functions as arguments, unlike in C.
The usefulness of this feature far surpasses the 'accidental errors'.
For example, you can do something like this:
# some code
def sum(a, b):
return a+b
def product(a, b):
return a*b
def ret_func(str):
if str=='add':
func = sum
elif str=='multiply':
func = product
return func
addition_result = ret_func('add')(x, y)
multiplication_result = ret_func('multiply')(x, y)
# some more code

Custom Python Data Structure

I have a class that wraps around python deque from collections. When I go and create a deque x=deque(), I create a empty deque object. So if I fill it up: x.append(0) and simply type in x on the console, i get:
In[78]: x
Out[78]: deque([0])
My question is how can I output the same thing as above when I have a wrapper for class deque. For example.
class deque_wrapper:
def __init__(self):
self.data_structure = deque()
def newCustomAddon(x):
return len(self.data_structure)
Ie
In[74]: x = deque_wrapper()
In[75]: x
Out[75]: <__main__.deque_wrapperat 0x7e3d0f0>
I want to customize what gets printed out as oppose to just a memory location. What can I do?
I want to customize what gets printed out as oppose to just a memory location. What can I do?
This is exactly what __repr__ is for:
Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.
Because you didn't define a __repr__, you're getting the default implementation from object (assuming Python 3… otherwise, you've written a classic class, which is a bad idea, and you don't want to learn how they get their defaults when you can just stop using them…), which just returns that string with the object's type name and address.
Note the __str__ method below __repr__ in the docs. If the most human-readable representation and the valid-Python-expression representation are not the same, define both methods. Otherwise, just define __repr__, and __str__ will use it by default.
So, if you want to print the exact same thing as deque, just delegate __repr__:
def __repr__(self):
return repr(self.data_structure)
If you want to wrap it in something:
def __repr__(self):
return '{}({!r})'.format(type(self).__name__, self.data_structure)
Note that I didn't call repr in the second version, because that's exactly what !r means in a format string. But really, in this case, you don't need either; a deque has the same str and repr.
Delegate the generation of the representation.
class deque_wrapper:
...
def __repr__(self):
return repr(self.data_structure)

How do I change the string representation of a Python class? [duplicate]

This question already has answers here:
How to print instances of a class using print()?
(12 answers)
Closed 4 years ago.
In Java, I can override the toString() method of my class. Then Java's print function prints the string representation of the object defined by its toString(). Is there a Python equivalent to Java's toString()?
For example, I have a PlayCard class. I have an instance c of PlayCard. Now:
>>> print(c)
<__main__.Card object at 0x01FD5D30>
But what I want is something like:
>>> print(c)
A♣
How do I customize the string representation of my class instances?
I'm using Python 3.x
The closest equivalent to Java's toString is to implement __str__ for your class. Put this in your class definition:
def __str__(self):
return "foo"
You may also want to implement __repr__ to aid in debugging.
See here for more information:
Special Method Names - Basic Customization
This is not as easy as it seems, some core library functions don't work when only str is overwritten (checked with Python 2.7), see this thread for examples
How to make a class JSON serializable
Also, try this
import json
class A(unicode):
def __str__(self):
return 'a'
def __unicode__(self):
return u'a'
def __repr__(self):
return 'a'
a = A()
json.dumps(a)
produces
'""'
and not
'"a"'
as would be expected.
EDIT: answering mchicago's comment:
unicode does not have any attributes -- it is an immutable string, the value of which is hidden and not available from high-level Python code. The json module uses re for generating the string representation which seems to have access to this internal attribute. Here's a simple example to justify this:
b = A('b')
print b
produces
'a'
while
json.dumps({'b': b})
produces
{"b": "b"}
so you see that the internal representation is used by some native libraries, probably for performance reasons.
See also this for more details: http://www.laurentluce.com/posts/python-string-objects-implementation/

Python object.__repr__(self) should be an expression?

I was looking at the builtin object methods in the Python documentation, and I was interested in the documentation for object.__repr__(self). Here's what it says:
Called by the repr() built-in function
and by string conversions (reverse
quotes) to compute the “official”
string representation of an object. If
at all possible, this should look like
a valid Python expression that could
be used to recreate an object with the
same value (given an appropriate
environment). If this is not possible,
a string of the form <...some useful
description...> should be returned.
The return value must be a string
object. If a class defines repr()
but not str(), then repr() is
also used when an “informal” string
representation of instances of that
class is required.
This is typically used for debugging,
so it is important that the
representation is information-rich and
unambiguous
The most interesting part to me, was...
If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value
... but I'm not sure exactly what this means. It says it should look like an expression which can be used to recreate the object, but does that mean it should just be an example of the sort of expression you could use, or should it be an actual expression, that can be executed (eval etc..) to recreate the object? Or... should it be just a rehasing of the actual expression which was used, for pure information purposes?
In general I'm a bit confused as to exactly what I should be putting here.
>>> from datetime import date
>>>
>>> repr(date.today()) # calls date.today().__repr__()
'datetime.date(2009, 1, 16)'
>>> eval(_) # _ is the output of the last command
datetime.date(2009, 1, 16)
The output is a string that can be parsed by the python interpreter and results in an equal object.
If that's not possible, it should return a string in the form of <...some useful description...>.
It should be a Python expression that, when eval'd, creates an object with the exact same properties as this one. For example, if you have a Fraction class that contains two integers, a numerator and denominator, your __repr__() method would look like this:
# in the definition of Fraction class
def __repr__(self):
return "Fraction(%d, %d)" % (self.numerator, self.denominator)
Assuming that the constructor takes those two values.
Guideline: If you can succinctly provide an exact representation, format it as a Python expression (which implies that it can be both eval'd and copied directly into source code, in the right context). If providing an inexact representation, use <...> format.
There are many possible representations for any value, but the one that's most interesting for Python programmers is an expression that recreates the value. Remember that those who understand Python are the target audience—and that's also why inexact representations should include relevant context. Even the default <XXX object at 0xNNN>, while almost entirely useless, still provides type, id() (to distinguish different objects), and indication that no better representation is available.
"but does that mean it should just be an example of the sort of expression you could use, or should it be an actual expression, that can be executed (eval etc..) to recreate the object? Or... should it be just a rehasing of the actual expression which was used, for pure information purposes?"
Wow, that's a lot of hand-wringing.
An "an example of the sort of expression you could use" would not be a representation of a specific object. That can't be useful or meaningful.
What is the difference between "an actual expression, that can ... recreate the object" and "a rehasing of the actual expression which was used [to create the object]"? Both are an expression that creates the object. There's no practical distinction between these. A repr call could produce either a new expression or the original expression. In many cases, they're the same.
Note that this isn't always possible, practical or desirable.
In some cases, you'll notice that repr() presents a string which is clearly not an expression of any kind. The default repr() for any class you define isn't useful as an expression.
In some cases, you might have mutual (or circular) references between objects. The repr() of that tangled hierarchy can't make sense.
In many cases, an object is built incrementally via a parser. For example, from XML or JSON or something. What would the repr be? The original XML or JSON? Clearly not, since they're not Python. It could be some Python expression that generated the XML. However, for a gigantic XML document, it might not be possible to write a single Python expression that was the functional equivalent of parsing XML.
'repr' means representation.
First, we create an instance of class coordinate.
x = Coordinate(3, 4)
Then if we input x into console, the output is
<__main__.Coordinate at 0x7fcd40ab27b8>
If you use repr():
>>> repr(x)
Coordinate(3, 4)
the output is as same as 'Coordinate(3, 4)', except it is a string. You can use it to recreate a instance of coordinate.
In conclusion, repr() method is print out a string, which is the representation of the object.
To see how the repr works within a class, run the following code, first with and then without the repr method.
class Coordinate (object):
def __init__(self,x,y):
self.x = x
self.y = y
def getX(self):
# Getter method for a Coordinate object's x coordinate.
# Getter methods are better practice than just accessing an attribute directly
return self.x
def getY(self):
# Getter method for a Coordinate object's y coordinate
return self.y
def __repr__(self): #remove this and the next line and re-run
return 'Coordinate(' + str(self.getX()) + ',' + str(self.getY()) + ')'
>>>c = Coordinate(2,-8)
>>>print(c)
I think the confusion over here roots from the english. I mean __repr__(); short for 'representation' of the value I'm guessing, like #S.Lott said
"What is the difference between "an actual expression, that can ... recreate the object" and "a rehasing of the actual expression which was used [to create the object]"? Both are an expression that creates the object. There's no practical distinction between these. A repr call could produce either a new expression or the original expression. In many cases, they're the same."
But in some cases they might be different. E.g; coordinate points, you might want c.coordinate to return: 3,5 but c.__repr__ to return Coordinate(3, 5). Hope that makes more sense...

Categories

Resources