简体   繁体   中英

Python's equivalence?

Is there anyway to transform the following code in Java to Python's equivalence?

public class Animal{

public enum AnimalBreed{

    Dog, Cat, Cow, Chicken, Elephant
}

private static final int Animals = AnimalBreed.Dog.ordinal();

    private static final String[] myAnimal = new String[Animals];
    private static Animal[] animal = new Animal[Animals];

    public static final Animal DogAnimal = new Animal(AnimalBreed.Dog, "woff");
    public static final Animal CatAnimal = new Animal(AnimalBreed.Cat, "meow");
    private AnimalBreed breed;

public static Animal myDog (String name) {
        return new Animal(AnimalBreed.Dog, name);

      }
}

Translating this code directly would be a waste of time. The hardest thing when moving from Java to Python is giving up most of what you know. But the simple fact is that Python is not Java , and translating line by line won't work as you expect. It's better to translate algorithms rather than code, and let Python do what it's good at.

It's unclear to me what the desired semantics of your Java would be. I'm guessing you're sort of trying to model a collection of animals (species, not breeds, incidentally) and imbue a set of associated classes with the behavior that varies according to the type of animal (roughly speaking the sounds that each makes).

In Python the natural way to do this would be through meta programming. You create a class or a factory function which returns each of the classes by passing arguments into a template. Since functions and classes are first order object in Python they can be passed around like any other object. Since classes are themselves objects you can access their attributes using setattr (and its cousins: hasattr and getattr ).

Here's a simple example:

#!/usr/bin/env python
def Animal(species, sound):
    class meta: pass

    def makeSound(meta, sound=sound):
        print sound
    setattr(meta, makeSound.__name__, makeSound)

    def name(meta, myname=species):
        return myname
    setattr(meta, 'name', name)
        return meta

if __name__ == '__main__':
    animal_sounds = (('Dog', 'woof'),
                     ('Cat', 'meow'),
                     ('Cow', 'moo'),
                     ('Chicken', 'cluck'),
                     ('Elephant', 'eraunngh'))

    menagerie = dict()
    for animal, sound in animal_sounds:
        menagerie[animal] = Animal(animal, sound)

    for Beast in menagerie:
        beast = Beast()
        print beast.name(), ' says ',
        beast.makeSound()

    Dog = menagerie['Dog']
    fido = Dog()   # equivalent to fido = menagerie['Dog']()
    fido.makeSound()
    # prints "woof"
    Cat = menagerie['Cat']
    felix = Cat()
    felix.makeSound()
    Mouse = Animal('Mouse', 'squeak')
    mickey = Mouse()
    mouse.makeSound()
    # prints "squeak"

This seems like a trite example but I hope it gets the point across. I can create a table (in this case a tuple of tuples) which provides the arguments which will be used to fill in the varying parameters/behavior of our classes. The classes returned by Animal are just like any other Python classes. I've tried to show that in the examples here.

This is not a line-for-line translation, but something in the ballpark:

class Animal(object):
    animal_breeds = "Dog Cat Cow Chicken Elephant".split()
    animals = {}

    def __init__(self, breed, name):
        self._breed = breed
        self.name = name
        Animal.animals[name] = self

    @property
    def breed(self):
        return Animal.animal_breeds[self._breed]

    @staticmethod
    def myDog(name):
        return Animal(Animal.AnimalBreed.Dog, name)

# add enumeration of Animal breeds to Animal class
class Constants(object): pass
Animal.AnimalBreed = Constants()
for i,b in enumerate(Animal.animal_breeds):
    setattr(Animal.AnimalBreed, b, i)

# define some class-level constant animals
# (although "woff" and "meow" are not what I would expect
# for names of animals)    
Animal.DogAnimal = Animal(Animal.AnimalBreed.Dog, "woff")
Animal.CatAnimal = Animal(Animal.AnimalBreed.Cat, "meow")

# this code would be in a separate module that would import this
# code using
#     from animal import Animal
#
print Animal.myDog("Rex").breed
print Animal.animals.keys()

http://code.activestate.com/recipes/413486/ contains a lot of help on this topic. Be warned that deepcopy support probably doesn't work with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM