[英]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.