gpt4 book ai didi

减少基类中小子类数量的 Pythonic 方法?

转载 作者:太空宇宙 更新时间:2023-11-03 11:29:11 25 4
gpt4 key购买 nike

我发现自己为预定义的对象编写了许多小的子类。但是,我创建的每个子类都包含大量重复代码(用于基类实例化)。本质上,我使用子类来存储默认的初始化属性,特定于子类,并为基类所共有。

使用许多只有 init() 的小子类是否可以接受?

例如:我创建了一个包含基类和子类的模块(我有 30 个子类,参数和默认参数略有不同)。

#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 子类在其他模块中创建实例(tab 完成是必不可少的,因此我可以引用特定的动物子类)。

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()

我发现使用具有许多预定义子类的基类可以创建更明确的代码,并允许将来扩展。尽管如此,这仍然会产生大量重复代码,而且我目前还没有用于子类的独特方法。感觉好像用错了classing?

我曾尝试使用变量来替换子类定义。如果我想修改任何东西,这会很麻烦,因为我必须记住默认值和它们的顺序,而且看起来不如子类化那么明确。

#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"])

我应该重新考虑在这种情况下使用子类吗?如果是这样,实现此目的的 Pythonic 方法是什么?

我应该考虑@classmethod 还是@staticmethod?我理解他们在理论上做了什么,但不知道如何/何时实现它们。


其他问题:

谢谢大家的回答。在回复之前我已经多次阅读它们,并提出了稍微修改过的例子来澄清我仍然难以理解的概念。我是 StackOverflow 的新手并以这种方式回复,以便我可以详细说明。如果这是对“编辑”的不当使用,请告诉我如何继续。

-我认为您认为在这种情况下可以接受子类化?

-我喜欢你的类变量技术。我计划实现它。

-我认为您对 **kwargs 的使用很有希望,但没有引用源 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)

这是有效的语法吗? Dog.kwargs 中的 cute=True 会超过我在实例化中设置 cute=False 吗?

关于分类学的有趣观点。幸运的是,我确实有有限数量的子类(我不需要一直特化),并且对于我的使用来说,通过 Animal 基类创建 Dog 不是 type(Dog) 是可以接受的。

考虑到这一点,还有其他需要考虑的概念吗?

最佳答案

我会使用 super 和 **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)

关于减少基类中小子类数量的 Pythonic 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26557364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com