Pythonic way to reduce the number of small subclasses in a base class?

I find that I am writing many small subclasses for predefined objects. However, every subclass that I create contains a lot of duplicate code (to create a base class). Essentially, I use subclasses to store the default initialization attributes specific to the subclass and common to the base class.

Is using many small subclasses only with init () acceptable using subclasses?

For example: I am creating a module that contains a base class and subclasses (I have 30 subclasses with slightly different default arguments and arguments).

#animals.py
#Contains animal definitions and methods
class Animal(object):
    def __init__(self, name, weight, cute=False, kind=None, image=None):
        #Instantiation attributes
        self.name = name
        self.weight = weight
        self.cute = cute
        self.kind = kind
        self.image = image
        #Attributes common to all animals
        self.extinct = False

    def get_animal_stats(self):
        print arbitrary_animal_stat

class Dog(Animal):
    def __init__(self, name, weight, kind="Mixed Breed"):
        Animal.__init__(self, name, weight, cute=True, kind=kind, image="dog.com")

class Cat(Animal):
    def __init__(self, name, weight):
        Animal.__init__(self, name, weight, cute=True, image="cat.com")

Animal , Animal ( , ).

import animals    #Uses animal definitions from animals.py

my_animals = [
    animals.Animal("Python", 2.7, cute=False),
    animals.Dog("Snoopy", 60, kind="Cartoon"),
    animals.Cat("Tigger", 50, kind="Tiger"),]

for animal in my_animals:
    animal.get_animal_stats()

, . , , . ?

. , - , , , .

#Use of variables instead of subclasses
dog = ("True", "Mixed Breed", "dog.com")

Animal("default dog", 60, *animals.dog)
Animal("special dog", 60, cute=False, kind="Guard Dog", image=animals.dog[2])

, , , .

#Use of dictionaries instead of subclasses
dog = {"cute": True, "kind": "Mixed Breed", "image": "dog.com"}

Animal("default dog", 60, **animals.dog)
Animal("special dog", 60, cute=False, kind="Guard Dog", image=animals.dog["image"])

? , ?

@classmethod @staticmethod? , , , .


:

. , , , , . StackOverflow , . "edit", , .

- , , ?

- . .

- , ** kwargs , source animals.py ', , - , ? .

- ** kwargs , . , , , ** kwargs ( ** kwargs).

class Dog(Animal):
    WOOF, YAP, HUSH = 'woof', 'yap', 'hush_puppy'
    kwargs = {cute: True, kind: "Generic", image_path: "dog.com"}
    def __init__(self, name, weight, bark=WOOF, **kwargs):
        self.bark = bark
        super(Dog, self).__init__(name, weight, **kwargs)


dog1 = Dog("Snoopy", 60, **Dog.kwargs)
dog2 = Dog("Otis", 30, bark=Dog.YAP, cute=False, **Dog.kwargs)

? = True Dog.kwargs = False ?

. , ( ), , Animal (Dog).

, , ?

+4
3

** kwargs - , .

class Dog(Animal):
    WOOF, YAP, HUSH = 'woof', 'yap', 'hush_puppy'
    def __init__(self, name, weight, bark=WOOF, **kwargs):
        self.bark = bark
        super(Dog, self).__init__(name, weight, **kwargs)

class Cat(Animal):
    HAIR_LONG, HAIR_SHORT = 'long', 'short'
    def __init__(self, name, weight,hair=HAIR_LONG, **kwargs):
        self.hair = hair
        super(Cat, self).__init__(name, weight, **kwargs)

dog = Dog("Snoopy", 60, bark=Dog.HUSH)
cat = Cat("Tigger", 50, kind="Tiger",hair=Cat.HAIR_SHORT)
+2

, , . , , . ** kwargs

Animal, , (, -, ?).

class Animal(object):
    def __init__(self, **kwargs):
        self.features = {k:v for k, v in kwargs.items()}

:

>>> dog = Animal(name="Rover", kind="mixed breed", weight="10kg")
>>> print dog.features['name']
Rover
>>> print dog.features['kind']
mixed breed

:

 >>> cat = Animal(name="Shredder", kind="tabby", cute="True")
 >>> print cat.features['name']
 Shredder
0

, Animal, ( Python), ( ) /.

, - , / /. , Fido Animal, Dog, , Fido. isinstnace(fido, Dog) False, Fido - . Python , , . , CLOS Prolog .

, . programers.stackexchange.com - , - stackoverflow, -, .


, , Python. : __init__ , kwarg, - .. . , . , , , , : options.

0

All Articles