0

My code is

dogs = []
cats = []

class dog:
    def __init__(self,name):
        self.name = name
        dogs.append(self)

class cat:
    def __init__(self,name):
        self.name = name
        cats.append(self)

dog1 = dog("steve")
dog2 = dog("dave")

cat1 = cat("simon")
cat2 = cat("elizabeth")

print(dogs[0], cats[0])

If i run this code it gives me

[<__main__.dog object at 0x7fc51434c6a0>, <__main__.cat object at 0x7fc51434c700>]

what is this called? and I want to try to get the name the animal use that code if i can

Later I want to have a player that can buy pets, and if player inputs "steve" it will add dog("steve") to players inventory using the codes up there.

My problem is that I do not know what it is called

최승규
  • 25
  • 4
  • 1
    The code shown will not produce that output. In fact it won't produce **any** output – DarkKnight Jul 31 '23 at 11:20
  • That's still not the output of your code, but what I can see is a list of two objects. You may want to look into the `__str__()` and `__repr__()` methods. – quamrana Jul 31 '23 at 11:20
  • Does this answer your question? [Python 3 REGEX .finditer: Usefulness of hex address in "callable\_iterator object at 0x..."?](https://stackoverflow.com/questions/63026106/python-3-regex-finditer-usefulness-of-hex-address-in-callable-iterator-object) – Joe Jul 31 '23 at 11:24
  • 1
    That output is what happens when you try to print a class that has neither the \_\_str__ nor \_\_repr__ dunder methods overridden – DarkKnight Jul 31 '23 at 11:26

4 Answers4

4

You can use magic method __repr__ to get the object str

dogs = []
cats = []

class dog:
    def __init__(self, name):
        self.name = name
        dogs.append(self)

    def __repr__(self):
        return self.name

class cat:
    def __init__(self, name):
        self.name = name
        cats.append(self)

    def __repr__(self):
        return self.name

dog1 = dog("steve")
dog2 = dog("dave")

cat1 = cat("simon")
cat2 = cat("elizabeth")
print(dogs)
print(cats)

output

[steve, dave]
[simon, elizabeth]
Cow
  • 2,543
  • 4
  • 13
  • 25
Xiaomin Wu
  • 400
  • 1
  • 5
  • This works, but it goes against best practice. To cite the documentation of [`__repr__`](https://docs.python.org/3/reference/datamodel.html#object.__repr__): "If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value". So `__repr__` for `dog` should be `return f'dog(self.name)'` and the name itself should be addressed via the attribute `name`. – Matthias Jul 31 '23 at 12:16
1

print will look for a class instance's __str__ function and call that (if it exists). If that doesn't exist it will look for __repr__ and call that (if it exists). If neither of those dunder method have been implemented you'll get the class type and its current address.

Appending to a global list in a class constructor will work but it's not a great solution.

You should look at this in a different way. You have two classes - dog & cat. They both represent animals. So... why not have an animal class to hold common attributes then subclass that for your different animal types.

Something like this:

class Animal:
    def __init__(self, name: str):
        self.name = name
    def __str__(self):
        return f'I am a {type(self).__name__} and my name is {self.name}'


class dog(Animal):
    def __init__(self, name: str):
        super().__init__(name)


class cat(Animal):
    def __init__(self, name):
        super().__init__(name)


dogs = [dog('steve'), dog('dave')]
cats = [cat('simon'), cat('elizabeth')]


print(*(dogs+cats), sep='\n')

Output:

I am a dog and my name is steve
I am a dog and my name is dave
I am a cat and my name is simon
I am a cat and my name is elizabeth
DarkKnight
  • 19,739
  • 3
  • 6
  • 22
0

in CPython, this is the memory address where the object is kept

You can add a __str__() and/or __repr__() method to return a string to display


However, it's generally better to have objects keep track of themselves (with an internal collection) or to put them into collections yourself, while you have the objects putting part of themselves into a collection external to them

class Dog:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return f"Dog({self.name})"

dogs = map(Dog, ("steve", "dave"))  # mapping
dogs = list(dogs)
>>> dogs
[Dog(steve), Dog(dave)]
>>> dogs[1].name
'dave'
ti7
  • 16,375
  • 6
  • 40
  • 68
0

You are just printing out the objects, which gives you the string representation of the object which by default looks like what you have posted here. If you want the string representation to give you just the name of the dog/cat then you have to override the __str__() or __repr__() method.

Alternatively you could just print out dogs[0].name and cats[0].name which is the more normal use case

Metareven
  • 822
  • 2
  • 7
  • 26