简体   繁体   中英

calling private methods for class method: python

I am trying to implement multiple constructors in python and one of the suggestions (through online searching) was to use the classmethod. However, using this, I am having issues with code reuse and modularity. Here is an example where I can create an object based on a supplied file or through some other means:

class Image:

    def __init__(self, filename):
         self.image = lib.load(filename)
         self.init_others()

    @classmethod
    def from_data(cls, data, header):
        cls.image = lib.from_data(data, header)
        cls.init_others()
        return cos

    def init_others(self):
        # initialise some other variables
        self.something = numpy.matrix(4,4)

Now it seems that I cannot do that. The cls.init_others() call fails by saying that I have not provided the object to call it on. I guess I can initialise things in the from_data function itself but then I repeat the code in the init method and the other "constructors". Does anyone know how I can call these other initialiser methods from these @classmethod marked functions? Or perhaps someone knows a better way to initialise these variables.

I come from a C++ background. So still trying to find my way around the python constructs.

I would recommend not trying to create multiple constructors, and use keyword arguments instead:

class Image(object):
    def __init__(self, filename=None, data=None, header=None):
         if filename is not None:
             self.image = lib.load(filename)
         elif data is not None and header is not None:
             self.image = lib.from_data(data, header)
         else:
             raise ValueError("You must provide filename or both data and header")
         self.init_others()

    def init_others(self):
        # initialise some other variables
        self.something = numpy.matrix(4,4)

This is a more Pythonic way to handle this scenario.

Your class method should create and return a new instance of the class, not assign class attributes and return the class itself. As an alternative to the keyword arguments, you could do something like:

class Image:

    def __init__(self, image):
        self.image = image
        self.init_others()

    @classmethod
    def from_data(cls, data, header):
        return cls(lib.from_data(data, header))

    @classmethod
    def from_filename(cls, filename):
        return cls(lib.load(filename))

    def init_others(self):
        # initialise some other variables
        self.something = numpy.matrix(4, 4)

This adds the ability to create an instance if you already have the image , too.

You should always pass in self as the first argument to any method that will act on a class instance. Python will not automatically determine the instance you're trying to call the method for unless you do that. So if you want to use a class function like

the_image = Image("file.txt")
the_image.interpolate(foo,bar)

You need to define the method within Image as

def interpolate(self,foo,bar):
  # Your code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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