如何通过遍历 __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)
我想知道是否有一种方法可以通过遍历 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)