如何通过遍历 __init__ 个参数来创建实例属性?

How to Create Instance Attributes By Lopping Over __init__ Arguments?

我想知道是否有一种方法可以通过遍历 init 方法的参数而不显式引用包含所有参数的列表来生成 class 属性init 方法的?

在下面的示例中,我可以遍历 hp、image、speed、x、y 来创建自变量吗?

class Character(pygame.sprite.Sprite):
    def __init__(self, hp, image, speed, x, y):

        # Call the parent class (Sprite) constructor
        super(Character, self).__init__()

        self.image = image
        self.rect = self.image.get_rect().move(x, y) #initial placement
        self.speed = speed
        self.hp = hp

例如,循环看起来像这样:

class Character(pygame.sprite.Sprite):
    def __init__(self, hp, image, speed, x, y):

        # Call the parent class (Sprite) constructor
        super(Character, self).__init__()

        for arg in arguments:
             self.arg = arg

我不太清楚如何让 "arguments" 指代 hp、image、speed、x 和 y?还是我坚持使用如下列表?

class Character(pygame.sprite.Sprite):
    def __init__(self, hp, image, speed, x, y):

        # Call the parent class (Sprite) constructor
        super(Character, self).__init__()

        for arg in [self, hp, image, speed, x, y]:
             self.arg = arg

您可以使用参数列表,但我不确定这是否是您想要的...

class Test(object):
    def __init__(self, *args):
        for arg in args:
            print(arg)

t = Test("one", 2, "three")

您可以使用 keyword arguments (kwargs) and define a list of attributes your instances require and you therefore expect in your __init__(). Then you can loop over them and assign your attributes via setattr:

class Character(pygame.sprite.Sprite):
    ATTRS = ('hp', 'image', 'speed', 'x', 'y')

    def __init__(self, **kwargs):
        # Call the parent class (Sprite) constructor
        super(Character, self).__init__()
        for attr in self.ATTRS:
            setattr(self, attr, kwargs.get(attr))  # sets to None if missing
        set_rect(...)  # do your processing of x, y

或者,更简单,只需将所有 kwargs 转换为实例属性:

class Character(pygame.sprite.Sprite):
    def __init__(self, **kwargs):
        super(Character, self).__init__()
        for key, value in kwargs.items():
            setattr(self, key, value)

但是,我会建议您不要使用这种诡计。它可能会使您的 __init__ 更短,但以后会影响您的工作效率,因为大多数 IDE 的(Eclipse-PyDev、PyCharm 等)代码 completion/resolution 功能将不会在现有实例上检测到此类动态设置的属性,也不会在调用构造函数时建议所需的参数,这对于使用您的 class.

的其他编码人员来说尤其烦人

它也不会使您的代码更具可读性。想象一下继承使用大量此类结构的代码库。您将学会喜欢一个干净的显式版本,就像您在问题中建议的第一个版本一样。缩短构造函数的折衷方案是使用 multiple assignment

self.image, self.speed, self.hp = image, speed, hp
self.rect = self.image.get_rect().move(x, y)