繁体   English   中英

从Python中的基类对象创建对象

[英]Creating an object from a base class object in Python

我有一个基类:

class Animal(object):
    def __init__(self, name=None, food=None):
        self.name = name
        self.food = food

    def eat(self):
        print "The %s eats some %s" % (self.name, self.food)

还有一个扩展它的类:

class Pet(Animal):
    def pet(self):
        print "You pet the %s." % self.name
    def feed(self):
        print "You put some %s into the bowl." % self.food
        self.eat()

假设我有一个Animal对象,它是这样创建的:

>>> fluffy_as_animal = Animal('dog', 'kibbles')

在python中有没有一种直接的方法可以从fluffy_as_animal创建Pet对象,而实际上没有写出来:

>>>> fluffy_as_pet = Pet(fluffy_as_animal.name, fluffy_as_animal.food)

更新资料

我执行此实现的原因是,我有一个带有一个函数的类,该函数返回一组Animal类型的对象,而这些对象我实际上都想用作Pet对象:

class AnimalStore(object):
    def fetch(count, query=None, server=None, *args, **kwargs):
        connection = connect_to_server(server)
        resp = connection.fetch_animals(query)
        objects = parse_response(resp)
        animals = []
        for a in objects[:count]:
            animals.append(Animal(a['name'], a.['food']))
        return animals

class PetStore(AnimalStore):
    def fetch(count, query=None, server=None, *args, **kwargs):
        query = 'type=pet AND %s' % query
        animals = super(PetFactory, self).fetch(count, query, server, *args, **kwargs)
        pets = []
        for animal in animals:
            pets.append(magic_function(animal))
        return pets

AnimalStorePetStore在单独的模块中。 AnimalStore是标准Animal API的一部分,并且不会更改。 基本上,我想通过使用用于动物的相同机制来获取宠物列表来扩展Animal API,并且我希望能够利用Animal API已经为其Animal和Java提供的所有其他内置函数。 AnimalStore类。

您可以编写Pet__init__()来接受Animal的实例(或者实际上是具有必要属性的任何对象-鸭子输入!)以及各个属性。 然后,您可以只做fluffy_as_pet = Pet(fluffy_as_animal) 或者,如果您不想重载__init__() ,请提供一个类方法(例如Pet.from_object() )执行相同的操作。 即使您不控制AnimalPet类,也可以根据需要创建它们自己的子类。

但是,最好走得更远,不要编写只接受Animal而不接受Pet代码。 然后,您不必转换它。 鸭子类型再次声明-如果对象具有正确的属性,则无论其类型如何,都可以使用它。

你可以做

fluffy_as_pet = object.__new__(Pet)
fluffy_as_pet.__dict__ = fluffy_as_animal.__dict__.copy()

要么

from copy import copy
fluffy_as_pet = copy(fluffy_as_animal)
fluffy_as_pet.__class__ = Pet

但是,这两种方式都可能比简单的解决方案更像是破解。

我最终使用了委托(贷方应转到S.Lott ):

class Animal(object):
    def __init__(self, name=None, food=None):
        self.name = name
        self.food = food

    def eat(self):
        print "The %s eats some %s" % (self.name, self.food)

class Pet(object):
    def __init__(self, animal=None):
        self.animal = animal

    def __getattr__(self, key):
        return getattr(self.animal, key)

    def __setattr__(self, key, value):
        return setattr(self.animal, key, value)

    def eat(self):
        return self.animal.eat()

    def pet(self):
        print "You pet the %s." % self.name

    def feed(self):
        print "You put some %s into the bowl." % self.food
        self.eat()

我只希望我能正确实施它; 无论哪种方式,它都有效!

我个人将为此使用类方法:

class Animal(object):
    def __init__(self, name):
        self.name = name

    @classmethod
    def fetch(cls, name):
        # DB code left out intentionally.
        return cls(name)


class Dog(Animal):
    def bark(self):
        print("woof")

这样,调用Dog().get('fido')将返回Dog类型的对象,而Animal().get('Mickey')将返回Animal类型的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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