使用装饰器时覆盖静态变量的值

时间:2015-08-19 17:29:13

标签: python python-3.x inheritance decorator python-decorators

我创建了一个类如下的类:

public static class ImageHash
{
    private static async Task<string> GetBase64FromImageFile(StorageFile file)
    {
        return ComputeHash(await ConvertToByteArray(file));
    }

    private static string ComputeHash(byte[] buffer)
    {
        IBuffer input = buffer.AsBuffer();
        IBuffer hashed = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(input);

        return CryptographicBuffer.EncodeToBase64String(hashed);
    }

    public async static Task<byte[]> ConvertToByteArray(StorageFile imageFile)
    {
        byte[] srcPixels;
        RandomAccessStreamReference streamRef =
            RandomAccessStreamReference.CreateFromFile(imageFile);

        using (IRandomAccessStreamWithContentType fileStream =
            await streamRef.OpenReadAsync())
        {
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
            BitmapFrame frame = await decoder.GetFrameAsync(0);

            // I know the parameterless version of GetPixelDataAsync works for this image
            PixelDataProvider pixelProvider = await frame.GetPixelDataAsync();
            srcPixels = pixelProvider.DetachPixelData();
        }

        return srcPixels;
    }
}

如果我想 Simon 坐下,我可以这样做:

class Simon:

    name = 'Simon'

    @classmethod
    def says(cls, sentence):
        return '%s says: %s' % (cls.name, sentence)

要将 Simon 替换为其他名称,比如 Eva ,我可以将其子类化为:

>>> Simon.says('sit down')
'Simon says: sit down'

结果:

class Eva(Simon):

    name = 'Eva'

现在我想通过创建名为>>> Eva.says('stand up') 'Eva says: stand up' 的装饰器来更改为

to_past_tense

如果我这样做:

class Eva(Simon):

    name = 'Eva'

    def to_past_tense(self, func):
        def wrapper(*arg, **kw):
            present_tense = func(*arg, **kw)
            past_tense = present_tense.replace('says', 'said')
            return past_tense
        return wrapper

    @classmethod
    def says(cls, *arg, **kw):
        return cls.to_past_tense(cls, Simon.says)(*arg, **kw)

我期待的是:

>>> Eva.says('stand up')

但事实上我得到了这个

'Eva said: stand up'

如何覆盖该值?

而且,请帮助我提高标题,如果它不精确和明确,谢谢!

2 个答案:

答案 0 :(得分:2)

您正在使用Simon.says,检索绑定的类。

如果你想获得重写的类方法但是它绑定到当前类,请使用super() proxy object

@classmethod
def says(cls, *arg, **kw):
    return cls.to_past_tense(cls, super().says)(*arg, **kw)

super()对象将搜索类的MRO,在says上找到Simon方法,然后将其绑定到cls对象,因此{仍然会从cls.name

查找{1}}值
Eva

答案 1 :(得分:0)

我不完全确定你要在这里实现什么,但我想你需要将cls.says传递给方法:

return cls.to_past_tense(cls, cls.says)(*arg, **kw)