简体   繁体   English

如何在 class 定义中调用 class function ?

[英]How do I call a class function inside the class definition?

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))

I want to use the save() function inside the class block.我想在 class 块内使用save() function 。 I've tried MetaDate.save() and simply save() both of which throw errors我试过MetaDate.save()和简单地save()两者都抛出错误

Is there any way to achieve this?有什么办法可以做到这一点?

Edit编辑

Yes, maxSize is a class var and yes i can access it using cls.maxSize .是的, maxSize是一个 class var,是的,我可以使用cls.maxSize访问它。

Your question is very similar to one I asked once — Calling class staticmethod within the class body?您的问题与我曾经问过的问题非常相似 — 在 class 正文中调用 class 静态方法? — which is interesting because it means you could make it a static method instead and call it like this: — 这很有趣,因为这意味着您可以将其改为 static 方法并像这样调用它:

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

Here's another answer.这是另一个答案。

You can use a metaclass to workaround to the limitation that you can't reference the class in the class body (since the class doesn't exist yet).您可以使用元类来解决无法在 class 正文中引用 class 的限制(因为 class 尚不存在)。 You can create the class in the metaclass __new__() method and then modify it — in this case by calling a classmethod defined in it.您可以在元类__new__()方法中创建 class 然后修改它——在这种情况下,通过调用其中定义的类方法。 Here's what I mean:这就是我的意思:

import os
import pickle


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

        cls = type.__new__(meta, classname, bases, classdict)

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

            cls.data = data = {
                0: [],
                1: {'.': None,}
            }
            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)

Output produced from running it for the first time (ie when there was no preexisting sample.data file): Output 第一次运行(即没有预先存在的sample.data文件时)产生:

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

Note that the SSD class attribute is an open file — which is very strange, but that's what your code would do too, if it were runnable.请注意, SSD class 属性是一个打开的文件——这很奇怪,但如果它是可运行的,这也是你的代码会做的事情。

At the point when you call save , the class is not yet defined.在您调用save时,class 尚未定义。 One way to get around this is to use inheritance and define save in the base-class:解决此问题的一种方法是使用 inheritance 并在基类中定义save

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

class A(B):
    B.save()

Then of course, variables in the head of A are not known in B.save and have to be given as arguments to save .然后,当然, A头部的变量在B.save中是未知的,必须以 arguments 的形式给出才能save

Well, or like this:好吧,或者像这样:

class B:
    SSD = None

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

class A(B):
    B.SSD = 3.14

    B.save()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM