0

I have a static base class, which I want to encapsulate child classes. I cannot find the syntax to create the inner classes from within a static outer class.

Here's an example of what I want:

class Farm:
    my_pet_cat = Animal("Meeeeooowww", "Fluffy")

    class Animal:            
        def __init__(self, sound, fur):
            self.sound = sound
            self.fur = fur

        def speak(self):
            print(self.sound)

        def pet(self):
            return self.fur

NameError: name 'Animal' is not defined

I tried accessing Animal with self.Animal(...) but this didn't work, as obviously Farm doesn't have a self, being a static class and all. I also successfully accessed Animal if it is placed outside of Farm, but I want to encapsulate the Animal class within the Farm class.

Can this be done??

ChickenFeet
  • 2,653
  • 22
  • 26
  • There's no such thing as an "inner class" in Python. You don't typically need any. – deceze Jul 27 '18 at 12:40
  • Why do you need inner class at all? What are you trying to achieve? Do you want `Farm` to be a container of `Animal` objects or do you want it to be base class of `Animal`? Or something else? Anyway... your code would work if you put line `my_pet_cat = Animal("Meeeeooowww", "Fluffy")` **after** definition of `Animal`. – running.t Jul 27 '18 at 12:42
  • I am just hiding this stuff away. `Farm` is going to be available to the rest of the application - but `Animal` and other inner classes I want to be more "hidden", so I am encapsulating them within `Farm`. In my actual application it is used for UI Menus and Menu Items. – ChickenFeet Jul 27 '18 at 12:48

2 Answers2

3

Define Animal class before you reference it to create an instance.

class Farm:
    class Animal:            
        def __init__(self, sound, fur):
            self.sound = sound
            self.fur = fur

        def speak(self):
            print(self.sound)

        def pet(self):
            return self.fur

    my_pet_cat = Animal("Meeeeooowww", "Fluffy")
vishal
  • 1,081
  • 2
  • 10
  • 27
  • this answers the actual question, but it's quite likely that `my_pet_cat` should be an instance variable instantiated in `__init__` rather than a class variable. – Matthew Story Jul 27 '18 at 12:43
  • @MatthewStory, in my case it's fine. I want it to be a singleton kind of pattern. – ChickenFeet Jul 27 '18 at 12:45
  • 1
    @ChickenFeet this is a pretty weird way to do a singleton in python. The standard approches to doing that are covered here https://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons ... the top 3 answers are what you typically see. – Matthew Story Jul 27 '18 at 12:47
  • @MatthewStory okay thanks, I'll have a look :) I am trying to force a bit more structure into python, coming from C#. – ChickenFeet Jul 27 '18 at 12:52
0

Why not use a module named Farm and in the Farm module, define a class name Animal?

Charles Cao
  • 116
  • 4
  • The module is `farm` which has a class `Farm`. I am trying to hide away the classes in `Farm` so the rest of the application doesn't get crowded. Perhaps there isn't a need for this, since you can import individual classes from a module - but it's done now :p – ChickenFeet Jul 27 '18 at 12:50