如何在类定义中调用类函数?

问题描述

class MetaData():

    maxSize = 2**10

    # class deFinition code
    if not os.path.exists('sample.data'):
        SSD  = open('sample.data','wb+')
        data = {
            0: [],1: {'.': None,}
        }
        data[1]['~'] = data[1]

        MetaData.save()  # i want to call the save function here


    # class function
    @classmethod
    def save(cls):

        cls.SSD.seek(0)
        cls.SSD.write(b' ' * cls.maxSize)
        cls.SSD.seek(0)
        cls.SSD.write(pickle.dumps(cls.data))

我想在类块中使用 save() 函数。我试过 MetaDate.save() 和简单的 save() 两者都抛出错误

有什么办法可以实现吗?

编辑

是的,maxSize一个类 var,是的,我可以使用 cls.maxSize 访问它。

解决方法

您的问题与我曾经问过的问题非常相似 - Calling class staticmethod within the class body? - 这很有趣,因为这意味着您可以将其改为静态方法并像这样调用它:

import os
import pickle


class MetaData:
    maxSize = 2**10

    @staticmethod
    def save():
        SSD.seek(0)
        SSD.write(b' ' * cls.maxSize)
        SSD.seek(0)
        SSD.write(pickle.dumps(cls.data))

    # class definition code
    if not os.path.exists('sample.data'):
        SSD  = open('sample.data','wb+')
        data = {
            0: [],1: {'.': None,}
        }
        data[1]['~'] = data[1]

        save.__func__()  # Call the save function
,

这是另一个答案。

您可以使用元类来解决无法在类主体中引用该类的限制(因为该类尚不存在)。您可以在元类 __new__() 方法中创建类,然后对其进行修改 - 在本例中通过调用其中定义的类方法。这就是我的意思:

import os
import pickle


class MetaMetaData(type):
    def __new__(meta,classname,bases,classdict):

        cls = type.__new__(meta,classdict)

        if not os.path.exists('sample.data'):
            cls.SSD = open('sample.data','wb+')

            cls.data = data = {
                0: [],}
            }
            data[1]['~'] = data[1]

            cls.save()

        return cls


class MetaData(metaclass=MetaMetaData):
    maxSize = 2**10

    @classmethod
    def save(cls):
        cls.SSD.seek(0)
        cls.SSD.write(b' ' * cls.maxSize)
        cls.SSD.seek(0)
        cls.SSD.write(pickle.dumps(cls.data))

    # class definition code
    ...


if __name__ == '__main__':
    print(MetaData.data)

第一次运行产生的输出(即没有预先存在的 sample.data 文件时):

{0: [],'~': {...}}}

请注意,SSD 类属性是一个打开的文件 — 这很奇怪,但如果您的代码可以运行,它也会这样做。

,

在您调用 save 时,该类尚未定义。解决此问题的一种方法是使用继承并在基类中定义 save

class B:
    @classmethod
    def save(cls):
        print("Saving")

class A(B):
    B.save()

当然,A 头部的变量在 B.save 中是未知的,必须作为参数提供给 save

好吧,或者像这样:

class B:
    SSD = None

    @classmethod
    def save(cls):
        print(f"Saving {cls.SSD}")

class A(B):
    B.SSD = 3.14

    B.save()