Create new class instance from class method

后端 未结 6 2036
攒了一身酷
攒了一身酷 2020-12-23 19:39

I want to be able to create a new instance of an object by calling a method on an already instantiated object. For example, I have the object:

organism = Organ

相关标签:
6条回答
  • 2020-12-23 20:18

    I believe you are asking how to copy an object. Surprisingly (maybe), there is (almost) no standard method for this, and this is by design. The issue comes from the intrinsic ambiguity of the idea of copying, i.e.: when you copy an object property do you mean to copy it as reference (copy) or as value (deepcopy)?

    However, in the majority of cases you want a consistent behavior (deepcopy or copy for all properties), in this case you can use copy module as

    import copy
    new_obj = copy.copy(old_obj)
    

    or

    new_obj = copy.deepcopy(old_obj)
    

    In a generic case in which you want a more customized behavior, you use the same commands, but override the __copy__ and __deepcopy__ methods of your objects.

    See more answers for details and examples, e.g.: How to override the copy/deepcopy operations for a Python object?

    0 讨论(0)
  • 2020-12-23 20:24

    What about something like this:

    class Organism(object):
    
        population = []
    
        def __init__(self, name):
            self.name = name
            self.population.append(self)
        def have_one_child(self, name):
            return Organism(name)
        def reproduce(self, names):
            return [self.have_one_child(name) for name in names]
    

    Result:

    >>> a = Organism('a')
    >>> len(Organism.population)
    1
    >>> a.reproduce(['x', 'y', 'z']) # when one organism reproduces, children are added
                                     # to the total population
                                     # organism produces as many children as you state
    [<__main__.Organism object at 0x05F23190>, <__main__.Organism object at 0x05F230F0>, <__main__.Organism object at 0x05F23230>]
    >>> for ele in Organism.population:
    ...     print ele.name
    ... 
    a
    x
    y
    z
    >>> Organism.population[3].reproduce(['f', 'g'])
    [<__main__.Organism object at 0x05F231D0>, <__main__.Organism object at 0x05F23290>]
    >>> for ele in Organism.population:
    ...     print ele.name
    ... 
    a
    x
    y
    z
    f
    g
    
    0 讨论(0)
  • 2020-12-23 20:27
    from copy import copy                                                           
    
    class Organism(object):                                                         
    
        def __init__(self,name):                                                    
            self.name=name                                                          
    
        def setName(self,name):                                                     
            self.name=name                                                          
    
        def reproduce(self,childname):     
            #use deepcopy if necessary                                         
            cp = copy(self)                                                         
            cp.setName("descendant from " + self.name + " " + childname)            
            return cp                                                               
    
        def __str__(self):                                                          
            return self.name                                                        
    
    first = Organism("first")                                                       
    second = first.reproduce("second")                                              
    
    print first                                                                     
    print second 
    
    0 讨论(0)
  • 2020-12-23 20:30
    class Organism(object):
        def reproduce(self):
            #use self here to customize the new organism ...
            return Organism()
    

    Another option -- if the instance (self) isn't used within the method:

    class Organism(object):
        @classmethod
        def reproduce(cls):
            return cls()
    

    This makes sure that Organisms produce more Organisms and (hypothetical Borgs which are derived from Organisms produce more Borgs).

    A side benefit of not needing to use self is that this can now be called from the class directly in addition to being able to be called from an instance:

    new_organism0 = Organism.reproduce()  # Creates a new organism
    new_organism1 = new_organism0.reproduce()  # Also creates a new organism
    

    Finally, if both the instance (self) and the class (Organism or subclasses if called from a subclass) are used within the method:

    class Organism(object):
        def reproduce(self):
            #use self here to customize the new organism ...
            return self.__class__()  # same as cls = type(self); return cls()
    

    In each case, you'd use it as:

    organism = Organism()
    new_organism = organism.reproduce()
    
    0 讨论(0)
  • 2020-12-23 20:32

    The same way you did originally, but then you have to do something with it!

    organism = Organism() calls the class Organism (parentheses directly after a name is the "call" operation). This creates and returns a new instance of the class, which you then bind to the name organism.

    When you execute that line in the interpreter, you now have a variable organism referring to the new Organism instance you just created.

    When you write that line inside a function (including a method, because there's no difference between a method and a function "from the inside"), it does the same thing, but the variable organism is a local variable. Local variables are thrown away when the function is finished, so this does create a new Organism instance, but it doesn't achieve anything because you never gain access to it.

    Your function should return any information it wants to communicate to its caller. Any local variables that you don't return are only useful if you use those variables to create something you do return.

    Note that this has nothing to do with your particular problem of creating an instance inside a method; it's just how functions/methods work in general. You will need to learn how functions work before you can successfully write object-oriented programs using classes and instances; I would strongly suggest you work through some tutorials.

    0 讨论(0)
  • 2020-12-23 20:39

    why not simply use the copy module?

    import copy
    organism = Organism()
    replica = copy.deepcopy(organism)
    
    0 讨论(0)
提交回复
热议问题