问题
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. I've tried MetaDate.save()
and simply save()
both of which throw errors
Is there any way to achieve this?
Edit
Yes, maxSize
is a class var and yes i can access it using cls.maxSize
.
回答1:
Your question is very similar to one I asked once — Calling class staticmethod within the class body? — which is interesting because it means you could make it a static method instead and call it like this:
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
回答2:
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). You can create the class in the metaclass __new__()
method and then modify it — in this case by calling a classmethod defined in it. 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 (i.e. when there was no preexisting sample.data
file):
{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.
回答3:
At the point when you call save
, the class is not yet defined. One way to get around this is to use inheritance and define save
in the base-class:
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
.
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()
来源:https://stackoverflow.com/questions/65645419/how-do-i-call-a-class-function-inside-the-class-definition