SevgiAkten / pycellga

Cellular Genetic Algorithms in Python.
https://sevgiakten.github.io/pycellga/
MIT License
2 stars 1 forks source link

Direct access to private object members #5

Closed jbytecode closed 4 months ago

jbytecode commented 1 year ago

Suppose the class is defined as below:

class A:
    member = 0

    def init(self):
           ....

The instantiate the class A

myobject = A()

and then suppose you get member as

myobject.member = 56

This use of member fields is somehow problematic in some cases so we can avoid using members directly. It is better to call setter and getter functions (like in C# and Java):

class A:
    _member = 0

    def init(self):
           ....

   def setmember(self, value):
           self._member = value

    def getmember(self):
            return self._member

Since we have no private members in Python objects, it is convenient to define with an underscore, e.g. _member. So the final use becomes

myobject = A()
myobject.setmember(5)
print(myobject.getmember()) 

Note that list objects are passed with their references, rather than values. To prevent mutations, list objects can be recreated with the old values if it is necessary.

jbytecode commented 1 year ago

The commit above implements some getter and setter functions to Individual class. Note that the member fields are still accessed in the whole program, so I didn't underscore them yet.

SevgiAkten commented 1 year ago

I likened it to encapsulation for private members in C#, as you mentioned.

jbytecode commented 1 year ago

yes, Python classes encapsulate their object field members, static objects, and methods by default. However unexpected mutations are main causes of some problems so we hereby restrict the access of private members.

For example, suppose that we mutate the content of an Individual like that

parent.chromosome = [1,1,1,1,1]

this use of accessing of the field may be a cause of a problem, just because the fitness value should be updated whenever the content is changed so

def setchromosome(self, value):
      self.chromosome = value 
      self.fitness = self.problem.f(value)

guarantees that the change of content triggers the change of fitness at the same time.

Note: This use of setter is just an example so it does not mean that we really should change the definition of Individual. Please use this functionality when necessary.