【问题标题】:Is it possible to add an attribute to an imported class in python?是否可以在 python 中为导入的类添加属性?
【发布时间】:2014-08-13 01:32:28
【问题描述】:

我将解释我的情况,以便我的问题更有意义。

我正在使用 python 和 pygame 编写游戏。这是一款非常简约的游戏,没有很多图形,我希望每个关卡都是黑色或白色方块的网格。我认为将每个级别定义为一串 1 和 0 会更有意义

0000
0101
1010
1111

相对于:

level1 = (pygame.Rect(0, 0, 100, 100), pygame.Rect(100, 0, 100, 100),
pygame.rect(200, 0, 100, 100), pygame.rect(300, 0, 100, 100),
...
...

以此类推,以此类推每个矩形。第二种方式笨重且笨拙,并且会使设计关卡变得非常困难。同样在 python 中,可读性很重要,漂亮总比丑陋好。 =)

我打算使用第一种方式,并有一个函数返回一个 pygame.Rect 对象列表(类似于上面的代码),其中 0 是黑色瓷砖,1 是白色瓷砖。不幸的是,pygame.Rect 对象不包含关于它们是什么颜色的任何数据。

现在我的问题有两个。

1) 是否可以向现有类添加属性(在本例中,添加属性 rect.color),而无需进入它来自的模块的源代码并自己更改它? (因为这似乎是一个非常糟糕的主意。)

2) 如果上述情况可行,是否明智?还是你只是在踢自己的脚?

当然明白,我意识到这不是实现我想要的唯一方法。如果我想用久经考验的方法来做,我会创建一个像这样的类:

class tile:
    def __init__(self, x, y, width, height, color):
        self.rect = pygame.Rect(x, y, width, height)
        self.color = color

    def draw(self):
        pygame.draw.rect(displaysurface, self.color, self.rect)

这绝对是显而易见的方式,并且可以很好地满足我的需要。但是,我想知道这是否可能。如果是,它似乎在某些情况下非常有用。

****************************编辑************************ ******

好的,我接受了 shiplu.mokadd.im 的建议并尝试使用 setattr(),但这仅适用于我自己定义的类,而不适用于导入的类。这是一个例子:

class pet:
    def __init__(self, name, species):
        self.name = name
        self.species = species

fido = pet('Fido', 'Dog')
setattr(fido, 'breed', 'Golden Retriever')

print fido.breed

按预期输出“Golden Retriever”。但是这个例子:

import pygame

pygame.init()

rect = pygame.Rect(0, 10, 20, 30)

setattr(rect, 'color', "BLACK")
print rect.color

输出此错误。

Traceback (most recent call last):
  File "game.py", line 7, in <module>
    setattr(rect, 'color', "BLACK")
AttributeError: 'pygame.Rect' object has no attribute 'color'

我意识到我应该这样做:

class ColoredRect(Rect):
    def __init__(self, color, ...):
        self.color = color
        super(ColoredRed, self).__init__(self, ...)

但是有可能按照我一直在尝试的方式添加属性吗?

另外,我希望任何审查“可能重复”问题的人都意识到我并不是要添加方法... =)

【问题讨论】:

标签: python class attributes pygame


【解决方案1】:

是的,可以将属性添加到实例和类(也作为对象)。只需使用setattr

但是你为什么要这样做呢?你应该继承Rect 类并创建一个ColoredRect

class ColoredRect(Rect):
    def __init__(self, color, ...):
        self.color = color
        super(ColoredRed, self).__init__(self, ...)

【讨论】:

  • 应该注意的是,只有在类没有定义__slots__ 时才可能在实例上设置附加属性——出于性能原因,pygame.Rect 很可能就是这种情况。子类化删除了 __slots__ 及其对 的限制,但您也失去了对象是享元的好处。
  • pygame.Rectimplemented in C,因此在这种情况下,向实例添加属性无论如何都不起作用。
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
相关资源
最近更新 更多