Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将staticmethod与flyweight装饰器一起使用时出错_Python_Python 3.x_Decorator_Python Decorators_Flyweight Pattern - Fatal编程技术网

Python 将staticmethod与flyweight装饰器一起使用时出错

Python 将staticmethod与flyweight装饰器一起使用时出错,python,python-3.x,decorator,python-decorators,flyweight-pattern,Python,Python 3.x,Decorator,Python Decorators,Flyweight Pattern,我有一个制作精灵飞锤的课程,我用一个装饰师来命名这个课程。下面是一些代码: class flyweight: def __init__(self, cls): self._cls = cls self.__instances = dict() def __call__(self, title): return self.__instances.setdefault((title), self._cls(title)) 在这个问题

我有一个制作精灵飞锤的课程,我用一个装饰师来命名这个课程。下面是一些代码:

class flyweight:
    def __init__(self, cls):
        self._cls = cls
        self.__instances = dict()

    def __call__(self, title):
        return self.__instances.setdefault((title), self._cls(title))
在这个问题中,我将简化代码以显示相关内容

@flyweight
class Sprite:
    def __init__(self, title, surf=None):
        self.title = title
        self.surf = surf if surf is not None else pygame.image.load('Images/Sprites/'+title+'.png').convert_alpha()
        self.w, self.h = self.surf.get_size()

    @staticmethod
    def from_colour(colour, size=(40,40)):
        surf = pygame.Surface(size).convert(); surf.fill(colour)
        return Sprite(colour, surf)

red = Sprite.from_colour((125,0,0))
但这给了我一个错误:

AttributeError: 'flyweight' object has no attribute 'from_colour'

我应该重新设计我的flyweight实现还是有办法解决这个问题?

一旦装饰完成,包装对象的名称会自动指向装饰器返回的结果。在本例中,
Sprite
现在存储
flyweight
的一个实例,该实例又包含一个属性,该属性存储原始包装类
Sprite
的一个实例。例如,在声明后打印
Sprite
,得到:
。但是,可以从
\u cls
调用来自\u color的
静态方法:

red = Sprite._cls.from_colour((125,0,0))

一个
flyweight
装饰器确实应该将所有构造函数传递给底层类,包括
@classmethod
@staticmethod
替代构造函数。事实上,更一般地说,类装饰器确实应该保留包装的类的整个公共接口

而且,虽然我们可以很容易地修改
flyweight
以专门通过
Sprite
接口的其余部分,在本例中,这只是来自于_color
方法的
,但对于一个不那么琐碎的类,或者对于一个不断变化的类来说,这将是一个痛苦的过程。实际上,制作一个只适用于单个类的装饰器有什么意义

那么,让我们将其更改为:

  • 接受任何构造函数签名。理想情况下,我们希望在签名的哪个部分作为密钥进行配置,1但是为了避免事情变得太复杂,让我们将其作为第一个参数进行修复

  • 传递类的整个公共接口,而不仅仅是它的
    \uuu调用\uu
    接口

因此:



一,。我使用过的其他一些库对此函数memo缓存有很好的设计。可能是
cachetools
。对于类构造缓存来说,它应该同样有意义。

虽然这是可行的,但我认为这不是一个很好的答案。显然,
from_color
应该是
Sprite
公共界面的一部分。但是,您现在必须通过私有属性调用它。更糟糕的是,
Sprite
的用户不必知道的类的私有属性。特别是因为你应该能够在不改变任何东西的情况下将
@flyweight
放入并取出,除了性能,而且如果它模糊了装饰类的界面,你肯定不能。完美。谢谢
class flyweight:
    def __init__(self, cls):
        self._cls = cls
        self.__instances = dict()

    def __call__(self, key, *args, **kw):
        return self.__instances.setdefault(key, self._cls(key, *args, **kw))

    def __getattr__(self, name):
        if not name.startswith('_'):
            return getattr(self._cls, name)