1

I'm new to python (and coding in general) and I've been really struggling to wrap my head around classes. I feel like the concept of a class is just starting to click for me, but adding sub-classes (is that the same thing as a meta-class???) into the mix has confused me even more.

I've been trying to work my way through the python zoo project, by my friend's recommendation. The goal is to use classes and object oriented programming to create a program that can represent zoos which have cages, which have animals inside, and those animals have unique attributes. (here is the exercise if you want to look at it, but I'll provide the code relevant to my confusion https://github.com/gabits/zoo_exercise)

class Animal:
    """ Can be placed inside cages, and according to its place in food chain
    it has a list attribute of its prey (what it likes to eat).
    """

    prey = []

    def __init__(self):
        self.name = 'Unnamed'       # Default naming, to be modified

    def __repr__(self):
        """ Identifies the Animal by its name and species (subclass).
        """
        species = self.__class__.__name__
        return self.name + " " + species if self.name != 'Unnamed' else species


class Mouse(Animal):

    def __init__(self):
        super().__init__()


class Goat(Animal):

    def __init__(self):
        super().__init__()

My current understanding of this code:

  • We have the class Animal that gives the name 'unnamed' to each animal
  • The mouse and Goat classes are sub-classes of Animal

What I don't understand:

  • what __repr__, __class__, and __name__ each do
  • why do things dealing with classes all have the underscores before and after the variable? Does python treat these objects differently? or is the underscore just a naming scheme that signals something?
  • what the __repr__(self) function is doing

Any help is appreciated!

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Not directly related to your question (which is already answered by multiple duplicate questions) but it is bad practice to use dunder attributes when an alternative is available. It is better to use `type(self)` instead of `self.__class__`, for example. – Selcuk Jan 08 '20 at 04:51
  • @sshashank124 could you reopen my question please? I had already looked at both the similar questions you listed and in my opinion they were answering a more complicated question than mine. The first one you listed is about abstract classes, and this is just about normal classes. It would really help me if someone could explain the concepts I asked about on an example as simple as the one I provided. Thanks! – coding_guy69 Jan 08 '20 at 04:54
  • 1
    There is no such thing as an abstract class in Python, it is just that the person who asks that is not intending to instantiate that class, hence they named it `abstract1`. That question is a simple one and perfectly answers yours too. – Selcuk Jan 08 '20 at 04:57
  • @Selcuk: The `abc` module provides abstract class support. It's even mentioned in the top answer to that question. (Doesn't really change the applicability of the dupe target.) – user2357112 Jan 08 '20 at 05:06
  • @user2357112supportsMonica Well, yes and no. You are technically right in saying that there is some support, but (1) it is a library, and although backed with a PEP, not a language feature and (2) you can actually implement methods in ABCs, which makes them not exactly abstract. Edit: There is even a comment in the same question by Martijn Pieters: `An ABC can still be instantiated directly` – Selcuk Jan 08 '20 at 05:26
  • @Selcuk: You can implement methods in abstract classes in most languages with abstract classes. Java, for example. (I'm not sure what Martijn was thinking of with that particular comment, considering that direct instantiation of an abstract class *doesn't* work, even if you try to directly invoke `object.__new__` or something. You have to get crazy and indirect, like instantiating a different class and then setting `__class__` manually, or hit the bug where ABC instantiation protections don't work if you inherit from a C class that doesn't use `object.__new__`.) – user2357112 Jan 08 '20 at 05:32
  • @user2357112supportsMonica I stand corrected about my 2nd point, was thinking of interfaces. Regarding Martijn's comment; you can still instantiate an ABC subclass if it doesn't have any abstract methods. – Selcuk Jan 08 '20 at 05:38
  • @Selcuk: If it doesn't have any abstract methods, it's not an abstract class. (Python doesn't have a way to mark a class as abstract without having abstract methods. Inheriting from `abc.ABC` doesn't mean a class is abstract.) – user2357112 Jan 08 '20 at 05:44
  • `__repr__` is the method used to format a representation of an object; and to `print` it (in the absence of a `__str__` method). The `__class__.__name__` part just gets the class name to use in that display. Here it could produce 'Animal', or `'Goat'. `Try that `__repr__` in your own class. – hpaulj Jan 08 '20 at 06:40

0 Answers0