Changing `self` for another instance of same object?












0















I want to create a class, and all objects need to have a unique identifier key, and If I attempt to create a new instance of the object with a previously existent key, the instance should be the same as the one that already existing.



Similar to a singleton class, but in this case instead of one class, there are many but different.



My first approach was this



class Master:
existent = {}
def __init__(self, key, value=None):
try:
self = Master.existent[key]
return
except KeyError:
Master.existent[key] = self
# Rest of the __init__ method


But when I compare two objects, something like this A = Master('A', 0) and B = Master('B', 0), the B doesn't share any attributes that It should have, and if the Master class has any _method (single underscore), It also doesn't appear.



Any Idea how could I do this?



I think this is similar to the Factory Methods Pattern, but I'm still having trouble to find the parallels, or how to implemented in an elegant form.



EDIT:



The class basically has two proprieties and that's it, but many things would Inherit and/or contain instances of this as type, the easy way I thought I could do it, was extracting the properties from the existing instance corresponding to said key, assigning them to the new instance and abuse from the fact that they will have same hash output and the the equal operator will behave according to hashes so I can use == and is operators with no problem.



This Idea solves my problem, but overall I think this could be a common or interesting enough scenario to tackle.










share|improve this question





























    0















    I want to create a class, and all objects need to have a unique identifier key, and If I attempt to create a new instance of the object with a previously existent key, the instance should be the same as the one that already existing.



    Similar to a singleton class, but in this case instead of one class, there are many but different.



    My first approach was this



    class Master:
    existent = {}
    def __init__(self, key, value=None):
    try:
    self = Master.existent[key]
    return
    except KeyError:
    Master.existent[key] = self
    # Rest of the __init__ method


    But when I compare two objects, something like this A = Master('A', 0) and B = Master('B', 0), the B doesn't share any attributes that It should have, and if the Master class has any _method (single underscore), It also doesn't appear.



    Any Idea how could I do this?



    I think this is similar to the Factory Methods Pattern, but I'm still having trouble to find the parallels, or how to implemented in an elegant form.



    EDIT:



    The class basically has two proprieties and that's it, but many things would Inherit and/or contain instances of this as type, the easy way I thought I could do it, was extracting the properties from the existing instance corresponding to said key, assigning them to the new instance and abuse from the fact that they will have same hash output and the the equal operator will behave according to hashes so I can use == and is operators with no problem.



    This Idea solves my problem, but overall I think this could be a common or interesting enough scenario to tackle.










    share|improve this question



























      0












      0








      0








      I want to create a class, and all objects need to have a unique identifier key, and If I attempt to create a new instance of the object with a previously existent key, the instance should be the same as the one that already existing.



      Similar to a singleton class, but in this case instead of one class, there are many but different.



      My first approach was this



      class Master:
      existent = {}
      def __init__(self, key, value=None):
      try:
      self = Master.existent[key]
      return
      except KeyError:
      Master.existent[key] = self
      # Rest of the __init__ method


      But when I compare two objects, something like this A = Master('A', 0) and B = Master('B', 0), the B doesn't share any attributes that It should have, and if the Master class has any _method (single underscore), It also doesn't appear.



      Any Idea how could I do this?



      I think this is similar to the Factory Methods Pattern, but I'm still having trouble to find the parallels, or how to implemented in an elegant form.



      EDIT:



      The class basically has two proprieties and that's it, but many things would Inherit and/or contain instances of this as type, the easy way I thought I could do it, was extracting the properties from the existing instance corresponding to said key, assigning them to the new instance and abuse from the fact that they will have same hash output and the the equal operator will behave according to hashes so I can use == and is operators with no problem.



      This Idea solves my problem, but overall I think this could be a common or interesting enough scenario to tackle.










      share|improve this question
















      I want to create a class, and all objects need to have a unique identifier key, and If I attempt to create a new instance of the object with a previously existent key, the instance should be the same as the one that already existing.



      Similar to a singleton class, but in this case instead of one class, there are many but different.



      My first approach was this



      class Master:
      existent = {}
      def __init__(self, key, value=None):
      try:
      self = Master.existent[key]
      return
      except KeyError:
      Master.existent[key] = self
      # Rest of the __init__ method


      But when I compare two objects, something like this A = Master('A', 0) and B = Master('B', 0), the B doesn't share any attributes that It should have, and if the Master class has any _method (single underscore), It also doesn't appear.



      Any Idea how could I do this?



      I think this is similar to the Factory Methods Pattern, but I'm still having trouble to find the parallels, or how to implemented in an elegant form.



      EDIT:



      The class basically has two proprieties and that's it, but many things would Inherit and/or contain instances of this as type, the easy way I thought I could do it, was extracting the properties from the existing instance corresponding to said key, assigning them to the new instance and abuse from the fact that they will have same hash output and the the equal operator will behave according to hashes so I can use == and is operators with no problem.



      This Idea solves my problem, but overall I think this could be a common or interesting enough scenario to tackle.







      python design-patterns singleton factory-pattern






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 '18 at 6:33







      ekiim

















      asked Nov 15 '18 at 3:35









      ekiimekiim

      198210




      198210
























          3 Answers
          3






          active

          oldest

          votes


















          1














          Inspired by the answer from A Kruger, I have another solution building off the use of the __new__ method as suggested. The main difference in this answer is that there is no need to create an inner __Master class. The __new__ method is automatically called when Master() is invoked, and is expected to return an instance of the Master class. In my answer, the __new__ method returns a new instance, if needed, but returns an instance from the existent dictionary, if possible. Note that the user accesses the Master class as usual, i.e., they just call Master('A', 0). This is made possible by making the Master class extend object.



          Here is the code:



          class Master(object):
          existent = {}

          def __init__(self, key, value=None):
          self.key = key
          self.value = value
          if not key in Master.existent:
          Master.existent[key] = self

          def __new__(cls, *args, **kwargs):
          key = args[0]
          if key in Master.existent:
          return Master.existent[key]
          else:
          return super(Master, cls).__new__(cls)

          def __str__(self):
          return('id: ' + str(id(self)) + ', key=' + str(self.key) + ', value=' + str(self.value))

          A = Master('A', 0)
          print('A = ' + str(A))
          B = Master('A', 1)
          print('nAfter B created:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          B.value = 99
          print('nAfter B modified:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          C = Master('C', 3)
          print('nC = ' + str(C))


          And here is the output:



          A = id: 140023450750200, key=A, value=0

          After B created:
          B = id: 140023450750200, key=A, value=1
          A = id: 140023450750200, key=A, value=1

          After B modified:
          B = id: 140023450750200, key=A, value=99
          A = id: 140023450750200, key=A, value=99

          C = id: 140023450750256, key=C, value=3


          Note that A and B have the same id (they are the same object). Also note that changes to A or B affect each other, since they are the same object.






          share|improve this answer
























          • Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

            – A Kruger
            Nov 15 '18 at 15:56











          • After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

            – ekiim
            Nov 15 '18 at 16:41



















          1














          I don't think you can do that using the __init__() method, because a new instance of the class has already been created when that method is called. You probably need to create a factory type method something like:



          class Master:
          existent = {}
          init_OK = False

          def __init__(self, key, value=None):
          if not Master.init_OK:
          raise Exception('Direct call to Master() is not allowed')
          Master.init_OK = False
          self.key = key
          self.value = value
          Master.existent[key] = self

          @staticmethod
          def make(key, value=None):
          try:
          inst = Master.existent[key]
          except:
          Master.init_OK = True
          inst = Master(key, value=value)
          return inst





          share|improve this answer
























          • I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

            – ekiim
            Nov 15 '18 at 6:34





















          1














          You can use the __new__ method to handle this. You don't want to call __init__ unless you want to create a new object with a new key, and __new__ can be used to first check if the key is unique before calling __init__.



          class Master(object):

          instances = {}
          def __new__(cls, key, value=None):
          if key in Master.instances:
          return Master.instances[key]
          else:
          instance = super(Master, cls).__new__(cls)
          Master.instances[key] = instance
          return instance

          def __init__(self, key, value=None):
          self.value = value


          Then you can create the objects with



          >>> A = Master('A',0)
          >>> B = Master('B',0)
          >>> C = Master('A',1)


          Since A and C have the same key, they will point to the same object and will effectively be the same instance. Since C has the same key as A, it updates its value.



          >>> print(A.value)
          1


          Any new changes to A will be seen in C, and vice versa.



          >>> A.value = 5
          >>> print(C.value)
          5


          But changes to A and C will not affect B, and changes to B will not affect A or C.



          Edit:



          If you want to copy values but not instances, you could just store the values in the Master.instances dictionary and check if there's already values for the key.



          class Master(object):

          instances = {}
          def __init__(self, key, value=None):
          if key in Master.instances:
          self.value = Master.instances[key]
          else:
          self.value = value
          Master.instances[key] = value

          >>> A = Master('A',0)
          >>> C = Master('A',1)
          >>> print(C.value)
          0





          share|improve this answer


























          • I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

            – ekiim
            Nov 15 '18 at 6:25













          • I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

            – A Kruger
            Nov 15 '18 at 16:18











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53312057%2fchanging-self-for-another-instance-of-same-object%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Inspired by the answer from A Kruger, I have another solution building off the use of the __new__ method as suggested. The main difference in this answer is that there is no need to create an inner __Master class. The __new__ method is automatically called when Master() is invoked, and is expected to return an instance of the Master class. In my answer, the __new__ method returns a new instance, if needed, but returns an instance from the existent dictionary, if possible. Note that the user accesses the Master class as usual, i.e., they just call Master('A', 0). This is made possible by making the Master class extend object.



          Here is the code:



          class Master(object):
          existent = {}

          def __init__(self, key, value=None):
          self.key = key
          self.value = value
          if not key in Master.existent:
          Master.existent[key] = self

          def __new__(cls, *args, **kwargs):
          key = args[0]
          if key in Master.existent:
          return Master.existent[key]
          else:
          return super(Master, cls).__new__(cls)

          def __str__(self):
          return('id: ' + str(id(self)) + ', key=' + str(self.key) + ', value=' + str(self.value))

          A = Master('A', 0)
          print('A = ' + str(A))
          B = Master('A', 1)
          print('nAfter B created:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          B.value = 99
          print('nAfter B modified:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          C = Master('C', 3)
          print('nC = ' + str(C))


          And here is the output:



          A = id: 140023450750200, key=A, value=0

          After B created:
          B = id: 140023450750200, key=A, value=1
          A = id: 140023450750200, key=A, value=1

          After B modified:
          B = id: 140023450750200, key=A, value=99
          A = id: 140023450750200, key=A, value=99

          C = id: 140023450750256, key=C, value=3


          Note that A and B have the same id (they are the same object). Also note that changes to A or B affect each other, since they are the same object.






          share|improve this answer
























          • Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

            – A Kruger
            Nov 15 '18 at 15:56











          • After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

            – ekiim
            Nov 15 '18 at 16:41
















          1














          Inspired by the answer from A Kruger, I have another solution building off the use of the __new__ method as suggested. The main difference in this answer is that there is no need to create an inner __Master class. The __new__ method is automatically called when Master() is invoked, and is expected to return an instance of the Master class. In my answer, the __new__ method returns a new instance, if needed, but returns an instance from the existent dictionary, if possible. Note that the user accesses the Master class as usual, i.e., they just call Master('A', 0). This is made possible by making the Master class extend object.



          Here is the code:



          class Master(object):
          existent = {}

          def __init__(self, key, value=None):
          self.key = key
          self.value = value
          if not key in Master.existent:
          Master.existent[key] = self

          def __new__(cls, *args, **kwargs):
          key = args[0]
          if key in Master.existent:
          return Master.existent[key]
          else:
          return super(Master, cls).__new__(cls)

          def __str__(self):
          return('id: ' + str(id(self)) + ', key=' + str(self.key) + ', value=' + str(self.value))

          A = Master('A', 0)
          print('A = ' + str(A))
          B = Master('A', 1)
          print('nAfter B created:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          B.value = 99
          print('nAfter B modified:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          C = Master('C', 3)
          print('nC = ' + str(C))


          And here is the output:



          A = id: 140023450750200, key=A, value=0

          After B created:
          B = id: 140023450750200, key=A, value=1
          A = id: 140023450750200, key=A, value=1

          After B modified:
          B = id: 140023450750200, key=A, value=99
          A = id: 140023450750200, key=A, value=99

          C = id: 140023450750256, key=C, value=3


          Note that A and B have the same id (they are the same object). Also note that changes to A or B affect each other, since they are the same object.






          share|improve this answer
























          • Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

            – A Kruger
            Nov 15 '18 at 15:56











          • After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

            – ekiim
            Nov 15 '18 at 16:41














          1












          1








          1







          Inspired by the answer from A Kruger, I have another solution building off the use of the __new__ method as suggested. The main difference in this answer is that there is no need to create an inner __Master class. The __new__ method is automatically called when Master() is invoked, and is expected to return an instance of the Master class. In my answer, the __new__ method returns a new instance, if needed, but returns an instance from the existent dictionary, if possible. Note that the user accesses the Master class as usual, i.e., they just call Master('A', 0). This is made possible by making the Master class extend object.



          Here is the code:



          class Master(object):
          existent = {}

          def __init__(self, key, value=None):
          self.key = key
          self.value = value
          if not key in Master.existent:
          Master.existent[key] = self

          def __new__(cls, *args, **kwargs):
          key = args[0]
          if key in Master.existent:
          return Master.existent[key]
          else:
          return super(Master, cls).__new__(cls)

          def __str__(self):
          return('id: ' + str(id(self)) + ', key=' + str(self.key) + ', value=' + str(self.value))

          A = Master('A', 0)
          print('A = ' + str(A))
          B = Master('A', 1)
          print('nAfter B created:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          B.value = 99
          print('nAfter B modified:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          C = Master('C', 3)
          print('nC = ' + str(C))


          And here is the output:



          A = id: 140023450750200, key=A, value=0

          After B created:
          B = id: 140023450750200, key=A, value=1
          A = id: 140023450750200, key=A, value=1

          After B modified:
          B = id: 140023450750200, key=A, value=99
          A = id: 140023450750200, key=A, value=99

          C = id: 140023450750256, key=C, value=3


          Note that A and B have the same id (they are the same object). Also note that changes to A or B affect each other, since they are the same object.






          share|improve this answer













          Inspired by the answer from A Kruger, I have another solution building off the use of the __new__ method as suggested. The main difference in this answer is that there is no need to create an inner __Master class. The __new__ method is automatically called when Master() is invoked, and is expected to return an instance of the Master class. In my answer, the __new__ method returns a new instance, if needed, but returns an instance from the existent dictionary, if possible. Note that the user accesses the Master class as usual, i.e., they just call Master('A', 0). This is made possible by making the Master class extend object.



          Here is the code:



          class Master(object):
          existent = {}

          def __init__(self, key, value=None):
          self.key = key
          self.value = value
          if not key in Master.existent:
          Master.existent[key] = self

          def __new__(cls, *args, **kwargs):
          key = args[0]
          if key in Master.existent:
          return Master.existent[key]
          else:
          return super(Master, cls).__new__(cls)

          def __str__(self):
          return('id: ' + str(id(self)) + ', key=' + str(self.key) + ', value=' + str(self.value))

          A = Master('A', 0)
          print('A = ' + str(A))
          B = Master('A', 1)
          print('nAfter B created:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          B.value = 99
          print('nAfter B modified:')
          print('B = ' + str(B))
          print('A = ' + str(A))
          C = Master('C', 3)
          print('nC = ' + str(C))


          And here is the output:



          A = id: 140023450750200, key=A, value=0

          After B created:
          B = id: 140023450750200, key=A, value=1
          A = id: 140023450750200, key=A, value=1

          After B modified:
          B = id: 140023450750200, key=A, value=99
          A = id: 140023450750200, key=A, value=99

          C = id: 140023450750256, key=C, value=3


          Note that A and B have the same id (they are the same object). Also note that changes to A or B affect each other, since they are the same object.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 15:37









          John AndersonJohn Anderson

          3,4961515




          3,4961515













          • Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

            – A Kruger
            Nov 15 '18 at 15:56











          • After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

            – ekiim
            Nov 15 '18 at 16:41



















          • Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

            – A Kruger
            Nov 15 '18 at 15:56











          • After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

            – ekiim
            Nov 15 '18 at 16:41

















          Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

          – A Kruger
          Nov 15 '18 at 15:56





          Agreed -- I realized this as well and made the change to mine just before you posted this. Using the _Master subclass was derived from examples for singletons

          – A Kruger
          Nov 15 '18 at 15:56













          After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

          – ekiim
          Nov 15 '18 at 16:41





          After a while reading the Python Documentation and doing some tests, turns out the problem is that I didn't knew how __new__ actually works, your solution works perfectly as I need. I still need to resolve my issues with this method. Thanks

          – ekiim
          Nov 15 '18 at 16:41













          1














          I don't think you can do that using the __init__() method, because a new instance of the class has already been created when that method is called. You probably need to create a factory type method something like:



          class Master:
          existent = {}
          init_OK = False

          def __init__(self, key, value=None):
          if not Master.init_OK:
          raise Exception('Direct call to Master() is not allowed')
          Master.init_OK = False
          self.key = key
          self.value = value
          Master.existent[key] = self

          @staticmethod
          def make(key, value=None):
          try:
          inst = Master.existent[key]
          except:
          Master.init_OK = True
          inst = Master(key, value=value)
          return inst





          share|improve this answer
























          • I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

            – ekiim
            Nov 15 '18 at 6:34


















          1














          I don't think you can do that using the __init__() method, because a new instance of the class has already been created when that method is called. You probably need to create a factory type method something like:



          class Master:
          existent = {}
          init_OK = False

          def __init__(self, key, value=None):
          if not Master.init_OK:
          raise Exception('Direct call to Master() is not allowed')
          Master.init_OK = False
          self.key = key
          self.value = value
          Master.existent[key] = self

          @staticmethod
          def make(key, value=None):
          try:
          inst = Master.existent[key]
          except:
          Master.init_OK = True
          inst = Master(key, value=value)
          return inst





          share|improve this answer
























          • I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

            – ekiim
            Nov 15 '18 at 6:34
















          1












          1








          1







          I don't think you can do that using the __init__() method, because a new instance of the class has already been created when that method is called. You probably need to create a factory type method something like:



          class Master:
          existent = {}
          init_OK = False

          def __init__(self, key, value=None):
          if not Master.init_OK:
          raise Exception('Direct call to Master() is not allowed')
          Master.init_OK = False
          self.key = key
          self.value = value
          Master.existent[key] = self

          @staticmethod
          def make(key, value=None):
          try:
          inst = Master.existent[key]
          except:
          Master.init_OK = True
          inst = Master(key, value=value)
          return inst





          share|improve this answer













          I don't think you can do that using the __init__() method, because a new instance of the class has already been created when that method is called. You probably need to create a factory type method something like:



          class Master:
          existent = {}
          init_OK = False

          def __init__(self, key, value=None):
          if not Master.init_OK:
          raise Exception('Direct call to Master() is not allowed')
          Master.init_OK = False
          self.key = key
          self.value = value
          Master.existent[key] = self

          @staticmethod
          def make(key, value=None):
          try:
          inst = Master.existent[key]
          except:
          Master.init_OK = True
          inst = Master(key, value=value)
          return inst






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 4:31









          John AndersonJohn Anderson

          3,4961515




          3,4961515













          • I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

            – ekiim
            Nov 15 '18 at 6:34





















          • I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

            – ekiim
            Nov 15 '18 at 6:34



















          I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

          – ekiim
          Nov 15 '18 at 6:34







          I would really like that the user doesn't bother using the factory method, and that he can instantiate the object as if it where a regular python object, the factory method It's explicit for the programmer but, not that clear the user of the module if you consider they could be not as familiar with this design pattern thingy or OO in genera, the Idea is that the user of the module, is at a basic python level. This works, but doesn't fully solve the issue, check my edit of the question.

          – ekiim
          Nov 15 '18 at 6:34













          1














          You can use the __new__ method to handle this. You don't want to call __init__ unless you want to create a new object with a new key, and __new__ can be used to first check if the key is unique before calling __init__.



          class Master(object):

          instances = {}
          def __new__(cls, key, value=None):
          if key in Master.instances:
          return Master.instances[key]
          else:
          instance = super(Master, cls).__new__(cls)
          Master.instances[key] = instance
          return instance

          def __init__(self, key, value=None):
          self.value = value


          Then you can create the objects with



          >>> A = Master('A',0)
          >>> B = Master('B',0)
          >>> C = Master('A',1)


          Since A and C have the same key, they will point to the same object and will effectively be the same instance. Since C has the same key as A, it updates its value.



          >>> print(A.value)
          1


          Any new changes to A will be seen in C, and vice versa.



          >>> A.value = 5
          >>> print(C.value)
          5


          But changes to A and C will not affect B, and changes to B will not affect A or C.



          Edit:



          If you want to copy values but not instances, you could just store the values in the Master.instances dictionary and check if there's already values for the key.



          class Master(object):

          instances = {}
          def __init__(self, key, value=None):
          if key in Master.instances:
          self.value = Master.instances[key]
          else:
          self.value = value
          Master.instances[key] = value

          >>> A = Master('A',0)
          >>> C = Master('A',1)
          >>> print(C.value)
          0





          share|improve this answer


























          • I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

            – ekiim
            Nov 15 '18 at 6:25













          • I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

            – A Kruger
            Nov 15 '18 at 16:18
















          1














          You can use the __new__ method to handle this. You don't want to call __init__ unless you want to create a new object with a new key, and __new__ can be used to first check if the key is unique before calling __init__.



          class Master(object):

          instances = {}
          def __new__(cls, key, value=None):
          if key in Master.instances:
          return Master.instances[key]
          else:
          instance = super(Master, cls).__new__(cls)
          Master.instances[key] = instance
          return instance

          def __init__(self, key, value=None):
          self.value = value


          Then you can create the objects with



          >>> A = Master('A',0)
          >>> B = Master('B',0)
          >>> C = Master('A',1)


          Since A and C have the same key, they will point to the same object and will effectively be the same instance. Since C has the same key as A, it updates its value.



          >>> print(A.value)
          1


          Any new changes to A will be seen in C, and vice versa.



          >>> A.value = 5
          >>> print(C.value)
          5


          But changes to A and C will not affect B, and changes to B will not affect A or C.



          Edit:



          If you want to copy values but not instances, you could just store the values in the Master.instances dictionary and check if there's already values for the key.



          class Master(object):

          instances = {}
          def __init__(self, key, value=None):
          if key in Master.instances:
          self.value = Master.instances[key]
          else:
          self.value = value
          Master.instances[key] = value

          >>> A = Master('A',0)
          >>> C = Master('A',1)
          >>> print(C.value)
          0





          share|improve this answer


























          • I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

            – ekiim
            Nov 15 '18 at 6:25













          • I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

            – A Kruger
            Nov 15 '18 at 16:18














          1












          1








          1







          You can use the __new__ method to handle this. You don't want to call __init__ unless you want to create a new object with a new key, and __new__ can be used to first check if the key is unique before calling __init__.



          class Master(object):

          instances = {}
          def __new__(cls, key, value=None):
          if key in Master.instances:
          return Master.instances[key]
          else:
          instance = super(Master, cls).__new__(cls)
          Master.instances[key] = instance
          return instance

          def __init__(self, key, value=None):
          self.value = value


          Then you can create the objects with



          >>> A = Master('A',0)
          >>> B = Master('B',0)
          >>> C = Master('A',1)


          Since A and C have the same key, they will point to the same object and will effectively be the same instance. Since C has the same key as A, it updates its value.



          >>> print(A.value)
          1


          Any new changes to A will be seen in C, and vice versa.



          >>> A.value = 5
          >>> print(C.value)
          5


          But changes to A and C will not affect B, and changes to B will not affect A or C.



          Edit:



          If you want to copy values but not instances, you could just store the values in the Master.instances dictionary and check if there's already values for the key.



          class Master(object):

          instances = {}
          def __init__(self, key, value=None):
          if key in Master.instances:
          self.value = Master.instances[key]
          else:
          self.value = value
          Master.instances[key] = value

          >>> A = Master('A',0)
          >>> C = Master('A',1)
          >>> print(C.value)
          0





          share|improve this answer















          You can use the __new__ method to handle this. You don't want to call __init__ unless you want to create a new object with a new key, and __new__ can be used to first check if the key is unique before calling __init__.



          class Master(object):

          instances = {}
          def __new__(cls, key, value=None):
          if key in Master.instances:
          return Master.instances[key]
          else:
          instance = super(Master, cls).__new__(cls)
          Master.instances[key] = instance
          return instance

          def __init__(self, key, value=None):
          self.value = value


          Then you can create the objects with



          >>> A = Master('A',0)
          >>> B = Master('B',0)
          >>> C = Master('A',1)


          Since A and C have the same key, they will point to the same object and will effectively be the same instance. Since C has the same key as A, it updates its value.



          >>> print(A.value)
          1


          Any new changes to A will be seen in C, and vice versa.



          >>> A.value = 5
          >>> print(C.value)
          5


          But changes to A and C will not affect B, and changes to B will not affect A or C.



          Edit:



          If you want to copy values but not instances, you could just store the values in the Master.instances dictionary and check if there's already values for the key.



          class Master(object):

          instances = {}
          def __init__(self, key, value=None):
          if key in Master.instances:
          self.value = Master.instances[key]
          else:
          self.value = value
          Master.instances[key] = value

          >>> A = Master('A',0)
          >>> C = Master('A',1)
          >>> print(C.value)
          0






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 15 '18 at 16:26

























          answered Nov 15 '18 at 4:50









          A KrugerA Kruger

          1,35827




          1,35827













          • I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

            – ekiim
            Nov 15 '18 at 6:25













          • I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

            – A Kruger
            Nov 15 '18 at 16:18



















          • I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

            – ekiim
            Nov 15 '18 at 6:25













          • I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

            – A Kruger
            Nov 15 '18 at 16:18

















          I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

          – ekiim
          Nov 15 '18 at 6:25







          I tried something like this with the new method, but the interface for the object would involve the use of new keyword, and that doesn't feel that pythonic, but It does work, It feels more OO, but I'm not sure, I really want it to be as if you where instantiating a regular python object.

          – ekiim
          Nov 15 '18 at 6:25















          I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

          – A Kruger
          Nov 15 '18 at 16:18





          I see, if you just want to copy values, you can just store those values in the Master.instances dictionary. Edited answer.

          – A Kruger
          Nov 15 '18 at 16:18


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53312057%2fchanging-self-for-another-instance-of-same-object%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Lugert, Oklahoma