Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class returning value

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.

like image 662
Harry Hache Avatar asked Sep 13 '12 18:09

Harry Hache


People also ask

Can Python class return value?

You can use any Python object as a return value. Since everything in Python is an object, you can return strings, lists, tuples, dictionaries, functions, classes, instances, user-defined objects, and even modules or packages.

How do you get a class value in Python?

Use dot notation or getattr() function to get the value of a class attribute. Use dot notation or setattr() function to set the value of class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime.

Can __ init __ return value Python?

__init__ method returns a value The __init__ method of a class is used to initialize new objects, not create them. As such, it should not return any value. Returning None is correct in the sense that no runtime error will occur, but it suggests that the returned value is meaningful, which it is not.

Does __ init __ return anything?

__init__ doesn't return anything and should always return None .


1 Answers

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:

  1. Take a look at this guide to magic method use in Python.
  2. 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]) 
like image 135
Francis Avila Avatar answered Sep 18 '22 17:09

Francis Avila