如何为类的所有实例运行方法

Posted

技术标签:

【中文标题】如何为类的所有实例运行方法【英文标题】:How do I run a method for all instances of the class 【发布时间】:2022-01-22 12:44:30 【问题描述】:
class Planet:
  def __init__(self, name, radius, colour, speed, distance, mass, angle, orbitcentrex, 
  orbitcentrey):
    self.x = None
    self.y = None
    self._name = name
    self._radius = radius
    self._colour = colour
    self._speed = speed
    self._distance = distance
    self._angle = angle
    self._centreX = orbitcentrex
    self._centreY = orbitcentrey  

  def updateSpeed(*planets):
    planets._speed += (0.2*(planets._speed))

Sun = Planet("Sun", 50, SunColour, 0, 0, 0, 0, size[0] / 2, size[1] / 2)
Mercury = Planet("Mercury", 4, MercuryColour, 0.00477, 70, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Venus = Planet("Sun", 5.5, VenusColour, 0.00354, 125, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Earth = Planet("Earth", 6, EarthColour, 0.003, 180, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Mars = Planet("Mars", 4, MarsColour, 0.002424, 235, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Jupiter = Planet("Jupiter", 17, JupiterColour, 0.001317, 290, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Saturn = Planet("Saturn", 12, SaturnColour, 0.000975, 345, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Uranus = Planet("Uranus", 10, UranusColour, 0.000684, 400, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Neptune = Planet("Neptune", 10, NeptuneColour, 0.000546, 455, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)
Pluto = Planet("Pluto", 4, PlutoColour, 0.000471, 510, 0, random.uniform(0, 6.2832), size[0] / 2, size[1] / 2)

for event in pygame.event.get():
  if event.type == pygame.MOUSEBUTTONDOWN and 30 < Mouse[0] < 195 and 155 < Mouse[1] < 220:
    Planet.updateSpeed(Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto)

在运行 updateSpeed 方法时,我正在尝试使用 *args 将我所有的行星作为参数传递。但是它不能这样做,因为 *args 创建了一个行星名称的元组。有什么办法可以解决这个问题,所以我不必写单独的行来改变每个行星的速度。我之前是这样的:

if event.type == pygame.MOUSEBUTTONDOWN and 30 < Mouse[0] < 195 and 250 < Mouse[1] < 315:
  click.play()
  Mercury._speed += 0.002862
  Venus._speed += 0.002124
  Earth._speed += 0.0018
  Mars._speed += 0.0014544
  Jupiter._speed += 0.0007902
  Saturn._speed += 0.0005850
  Uranus._speed += 0.0004104
  Neptune._speed += 0.0003276
  Pluto._speed += 0.0002826

我想要的是这样的:

if event.type == pygame.MOUSEBUTTONDOWN and 30 < Mouse[0] < 195 and 155 < Mouse[1] < 220:
  Planet.updateSpeed(Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto)

【问题讨论】:

planets 是一个元组,因此您可以迭代其元素并单独应用更新。我不明白为什么该方法应该是类的一部分。 【参考方案1】:

您可以使用列表推导或映射来更改多个类。

    class Foo:
        def __init__(self, integer):
            self.integer = integer
    
        def add_one(self):
            self.integer += 1
            return self
    
        def __str__(self):
            return self.integer
    
    Foo1 = Foo(1)
    Foo2 = Foo(2)
    Foos = [Foo1, Foo2]
    print(f"Original Foos: [i.__str__() for i in Foos]")
    
    # Loop over Foos and apply add_one to each element.
    Foos = [i.add_one() for i in Foos]
    print(f"Changed Foos: [i.__str__() for i in Foos]")
    
    Foo1 = Foo(1)
    Foo2 = Foo(2)
    
    Foos = [Foo1, Foo2]
    print(f"Original Foos: [i.__str__() for i in Foos]")
    
    # Apply add_one to each element of Foos using a lambda function and using mapping.
    Foos = list(map(lambda x: x.add_one(), Foos))
    print(f"Changed Foos: [i.__str__() for i in Foos]")

【讨论】:

【参考方案2】:

使用for 循环遍历每个行星并更新其速度。

def updateSpeed(*planets):
    for planet in planets:
        planet._speed += (0.2 * (planet._speed))

【讨论】:

是的,我意识到自己有多愚蠢,但我忘了把问题记下来,哈哈【参考方案3】:

您可以列出要应用该方法的对象,并在 for 循环中应用所述方法

class Planet:
    def __init__(self,...):
        ... #same as yours

    def updateSpeed(self):
        self._speed *= 0.2

...
Planets = [Mercury, Venus,...]
for p in Planets:
    p.updateSpeed()

【讨论】:

以上是关于如何为类的所有实例运行方法的主要内容,如果未能解决你的问题,请参考以下文章

XML De/Serialization:如何为类的不同实例的相同属性定义不同的名称

如何为创建大量实例节省内存?

如何为机器上的所有 Bash 实例建立“共享”变量? [复制]

如何为多个选项卡/窗口运行工具栏的单个实例

如何为 AWS RDS 实例设置数据库时区 [重复]

如何为 Amazon EC2 实例设置 SSH 访问?