-4

Assume that we have a test()class defined as below :

>>> class test():
    pass

Normally when I run the below code I make Obj as an object of my test() class :

>>> obj=test()
>>> 
>>> obj
<__main__.test object at 0x00000000031B2390>
>>> type(obj)
<class '__main__.test'>
>>> 

As you see above obj has two features. It has a value and a type.

In the below, I assign Obj value as a string to another variable called var1 :

>>> var1='<__main__.test object at 0x00000000031B2390>'
>>> 
>>> type(var1)
<class 'str'>
>>> 

As you see above , obj1 and var1 are equal in value, but are different in type. And again, as you know we can change type of an object to string using str() function as below :

>>> Obj=str(Obj)
>>> Obj
'<__main__.test object at 0x00000000031B2390>'
>>> 

Now, I want to know if is there any way to reverse above function? I mean, Is there any way to make a string-type variable as a object?

I mean is there any way to make Var1 equal to Obj?

In the other word, assume that I know <__main__.test object at 0x00000000031B2390> is the value of an object of a class. But I don't know neither the name of the object nor the name of the class. Now I want to create another object of that class. Is there any way?

ti4programing
  • 13
  • 1
  • 4
  • 4
    *"`obj1` and `var1` are equal in value"* - what?! And that isn't the *"value"* of `obj`, just the default `__repr__` (representation) of the object. You seem to have fundamentally misunderstood what is going on here. – jonrsharpe Oct 03 '14 at 14:07
  • Do you want to create an object from just a class name or do you want some kind of serialisation? – tttthomasssss Oct 03 '14 at 14:08
  • @jonrsharpe Isn't the value of both equal to `<__main__.test object at 0x00000000031B2390>` ? – ti4programing Oct 03 '14 at 14:09
  • 2
    No. A test object is not at all the same thing as the string you see when you ask for its value. That's just a way of representing the object in a human-readable way. The object is actually a blob of memory (the long number is the location in memory where it's stored), and you cannot get from a string back to the actual object. It's like trying to recreate a house by picking up the numbers on the mailbox and putting them in another lot. – Mark Reed Oct 03 '14 at 14:09
  • @ti4programing what do you mean by *"value"*? – jonrsharpe Oct 03 '14 at 14:10
  • @tttthomasssss Assume that I know `<__main__.test object at 0x00000000031B2390>` is the value of an object of a class. But I don't know neither the name of that object nor the name of the class. Now I want to create another object of that class. Is there any way? – ti4programing Oct 03 '14 at 14:13
  • @jonrsharpe Value : I mean the statement that is returned when I type its name and press enter! – ti4programing Oct 03 '14 at 14:14
  • 1
    You know a name of the class: `__main__.test`. However, you don't know any of the details necessary to create a duplicate instance (Python does not let you work with arbitrary blobs of memory; the address is simply the value used by the interpreter as a unique integer identifier, nothing more.) – chepner Oct 03 '14 at 14:17
  • @ti4programing that's just the *representation* - except for simple types like `int` it doesn't make sense to call that a "value". – jonrsharpe Oct 03 '14 at 14:23
  • This entire conversation has already happened [here](http://stackoverflow.com/questions/1396668/python-get-object-by-id), and the [short answer is no, you can't easily get an object from its id](http://stackoverflow.com/a/1396696/786020). But it does have a brute force way to do it, which won't work with your code since `Obj=str(Obj)` will probably cause `Obj` to be cleaned up, as that removes the last reference of it in memory. – Poik Oct 03 '14 at 14:26

2 Answers2

1

There are a fair few misconceptions here.

First, it is untrue to say that a variable has two things, a value and a type. It has one thing only: a value. That value has a type. Variables in Python do not have types, they are simply names pointing at things.

Secondly, assigning a string that looks like the repr of an object does not somehow make the value equal to the object. A string is just a string.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • OK. Is there any way to transfer an string to an object? – ti4programing Oct 03 '14 at 14:17
  • No. You are missing the point that the string returned by `obj.__repr__` is in no way sufficient to recreate a copy of that object. – chepner Oct 03 '14 at 14:18
  • @chepner What I need to recreate an object without using `var1=test()` or `var1=obj`? Is it possible any way? – ti4programing Oct 03 '14 at 14:21
  • 2
    @ti4programing please (again) provide a **less abstract example**. Given that a `test` instance has no attributes or behaviour, what's the point of *"recreating"* it? And why do you need to do this; why do you only have the string, and where did it come from? – jonrsharpe Oct 03 '14 at 14:25
1

You are confusing the representation of an object (obj.__repr__(), or repr(obj)) with its value (which doesn't necessarily have a sensible meaning for all types of object *). Here is an example of an object with a misleading representation:

>>> a = 1
>>> a
1
>>> class FakeInt(object):
    def __repr__(self):
        return "1"


>>> b = FakeInt()
>>> b
1
>>> a == b
False
>>> a + b

Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    a + b
TypeError: unsupported operand type(s) for +: 'int' and 'FakeInt'

a looks like b, but isn't equal to it and cannot be used in the same way.

It is conventional to implement __repr__ and __eq__ instance methods such that eval(repr(obj)) == obj. This allows you to create new objects that are equal to the existing ones, for example:

>>> class SillyString(object):
    def __init__(self, s):
        self.string = s
    def __repr__(self):
        return "SillyString({0.string!r})".format(self)
    def __eq__(self, other):
        return self.string == other.string


>>> s = SillyString("foo")
>>> repr(s)
"SillyString('foo')"
>>> eval(repr(s)) == s
True # equal to s
>>> eval(repr(s)) is s 
False # but not identical to s, i.e. a separate object

However this seems pointless for your test objects, because they don't have attributes or methods to copy anyway.


* For example, here is an object definition:

def some_obj(object):

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

What should its "value" be? foo? bar? Some combination of the two?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437