[英]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
AnimalStore
和PetStore
在单独的模块中。 AnimalStore
是标准Animal
API的一部分,并且不会更改。 基本上,我想通过使用用于动物的相同机制来获取宠物列表来扩展Animal
API,并且我希望能够利用Animal API已经为其Animal
和Java提供的所有其他内置函数。 AnimalStore
类。
您可以编写Pet
的__init__()
来接受Animal
的实例(或者实际上是具有必要属性的任何对象-鸭子输入!)以及各个属性。 然后,您可以只做fluffy_as_pet = Pet(fluffy_as_animal)
。 或者,如果您不想重载__init__()
,请提供一个类方法(例如Pet.from_object()
)执行相同的操作。 即使您不控制Animal
和Pet
类,也可以根据需要创建它们自己的子类。
但是,最好走得更远,不要编写只接受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.