1

How to return a list from the class level using properties? When call instance a class it's all ok, but when it calls the attribute class, it gets the property object

below sample code:

class zoo:
    __count_animals=0
    __listAnimals=[]

    def __init__(self,typee,name,age):
        self.typee=typee
        self.name=name
        self.age=age
        self.__listAnimals.append(self)
        zoo.__count_animals+=1


    @property
    def count_animals(self):
        return self.__count_animals

    @count_animals.setter
    def count_animals(self,newvalue):
        newvalue=zoo.__ilosc_zwierzat
        self.__count_animals=newvalue

    @property
    def listAnimals(self):
        return  self.__listAnimals

    @listAnimals.setter
    def listAnimals(self,newobj):
        newobj=zoo.__listAnimals
        self.__listAnimals=newobj
  zw1=zoo("Tiger","NoName",23)
  print(zw1.listAnimals) # result it's ok ->[<__main__.zoo object at 0x006A23D0>, <__main__.zoo object at 0x006A2410>]

  but
  print(zoo.listAnimals) # result <property object at 0x002A1DB0>
Mican
  • 73
  • 5
  • 1
    Possible duplicate: https://stackoverflow.com/questions/5189699/how-to-make-a-class-property – DeepSpace Sep 15 '19 at 10:46
  • 1
    But what would you want to happen? The general class `zoo` doesn't have a list of animals, only the individual zoo instances do. – Daniel Roseman Sep 15 '19 at 10:47
  • Possible duplicate of [Python property on a list](https://stackoverflow.com/questions/37564798/python-property-on-a-list) – Diogo Rocha Sep 15 '19 at 10:50

2 Answers2

1

This works as expected. Because you are calling the property object on class instead on instance. Class does not hold the same data as class instances.

The way you expect it to happen is that __count_animals and __listAnimals are class properties instead of instance properties.

So I slightly modified your code to work with classproperties instead of instance properties.

Above I define classproperty decorator:

class classproperty(object):
    def __init__(self, f):
        self.f = f

    def __get__(self, obj, owner):
        return self.f(owner)

Then your class zoo

class zoo:
    __count_animals=0
    __listAnimals=[]

    def __init__(self,typee,name,age):
        self.typee=typee
        self.name=name
        self.age=age
        zoo.__listAnimals.append(self)
        zoo.__count_animals+=1

    @classproperty
    def count_animals(self):
        return self.__count_animals

    @classproperty
    def listAnimals(cls):
        return cls.__listAnimals


zw1=zoo("Tiger","NoName",23)
print(zoo.listAnimals) # result [<__main__.zoo object at 0x10699c410>]

Works like a charm!

Kryštof Řeháček
  • 1,965
  • 1
  • 16
  • 28
0

You are calling the class property, you need first to instance that class in to an object and then get the property of the object.

Rafaelars
  • 73
  • 5