# how expand a huge class in other script?

**URL:** <https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450>\
**Category:** Game Engine Support and Discussion\
**Created:** [December 25, 2012, 9:45am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450 "2012-12-25T09:45:59Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![MarcoIT](https://blenderartists.org/letter_avatar_proxy/v4/letter/m/22d042/32.png) [@MarcoIT](https://blenderartists.org/u/MarcoIT)\
**Post date:** [December 25, 2012, 9:45am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/1 "2012-12-25T09:45:59Z")

</div>

Hi

```auto

class A:
	def __init__ (self, own):
		self.x=0
		self.state = 1
		#(...)
	def Update(self):
		if self.state == 2 :
			updateClass(B) #&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;?????????
			
			
	def method1(self):
		pass
	def method2(self):
		pass
	def method3(self):
		pass
	def method4(self):
		pass

class B:
	def Update(self):
		if self.state == 3 :
			updateClass(C) #&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;?????????

def main(cont):
    own=cont.owner
    if not "init" in own:
        own["init"] = 1
        own["class"]=A(own)

own["class"].Update()
			

```

supposing that i have one class  
that become extremely long and full of dependences.  
how make to “refresh” the class ?  
i mean , how make to KEEP **init** (without resetting self.x)  
and change only Update() ? using a “newUpdate” that is in another script  
(and maybe keep the other method?)

I have found a way, but i’m curious to see other way(or if is the same)

i read something about “super()” but not work

---

<div class="post-metadata">

**Author:** ![Terry](https://blenderartists.org/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@Terry](https://blenderartists.org/u/Terry)\
**Post date:** [December 25, 2012, 10:06am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/2 "2012-12-25T10:06:12Z")

</div>

Maybe an implementation of the observer pattern using **call**?  
Just a guess though.

---

<div class="post-metadata">

**Author:** ![MarcoIT](https://blenderartists.org/letter_avatar_proxy/v4/letter/m/22d042/32.png) [@MarcoIT](https://blenderartists.org/u/MarcoIT)\
**Post date:** [December 25, 2012, 12:30pm UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/3 "2012-12-25T12:30:33Z")

</div>

what there of wrong on this ?

```auto

import bge

def Update1(self):
    self.val += 0.1
    if self.val &gt; 10.0 :
        self.Update = Update2
        
def Update2(self):
    self.val -= 0.1
    if self.val &lt; 0.0 :
        self.Update = Update1

class Base:
    def __init__ (self,own):
        self.owner = own
        self.val = 0.0
        
    def Main(self):
        self.Debug()
        self.Update()
        
    def Update(self):
        self.Update = Update1
        
    def Debug(self):
        self.owner["prop"] = self.val
        
        
        
def main(cont):
    own = cont.owner
    
    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)
        
        
    own["class"].Main()

```

I expect that Update() is refresh in to Update1 and then in Update2.  
so , self.val should run to 0\>\>10\>\>0\>\>10  
but a error occour -\> “self is missing”

---

<div class="post-metadata">

**Author:** ![agoose77](https://blenderartists.org/user_avatar/blenderartists.org/agoose77/32/442949_2.png) [@agoose77](https://blenderartists.org/u/agoose77)\
**Post date:** [December 25, 2012, 2:28pm UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/4 "2012-12-25T14:28:11Z")

</div>

> [@MarcoIT](#):
>
> what there of wrong on this ?
> 
> ```auto
> 
> import bge
> 
> def Update1(self):
> self.val += 0.1
> if self.val &gt; 10.0 :
> self.Update = Update2
>         
> def Update2(self):
> self.val -= 0.1
> if self.val &lt; 0.0 :
> self.Update = Update1
> 
> class Base:
> def __init__ (self,own):
> self.owner = own
> self.val = 0.0
>         
> def Main(self):
> self.Debug()
> self.Update()
>         
> def Update(self):
> self.Update = Update1
>         
> def Debug(self):
> self.owner["prop"] = self.val
>         
>         
>         
> def main(cont):
> own = cont.owner
>     
> if not "init" in own:
> own["init"] = 1
> own["class"] = Base(own)
>         
>         
> own["class"].Main()
> 
> ```
> 
> I expect that Update() is refresh in to Update1 and then in Update2.  
> so , self.val should run to 0\>\>10\>\>0\>\>10  
> but a error occour -\> “self is missing”

Class functions are bound to the instance when the class is instantiated. When you replace the old function with a new one, it is not bound (check for the **self** attribute of the function (there will be no attribute in the non-instantiated function)  
You want to “monkeypatch”. I would recommend against it; see the first post on this thread [http://stackoverflow.com/questions/394770/override-a-method-at-instance-level](http://stackoverflow.com/questions/394770/override-a-method-at-instance-level)  
but, for the sake of knowledge, the second post will help you to achieve your goal

---

<div class="post-metadata">

**Author:** ![MarcoIT](https://blenderartists.org/letter_avatar_proxy/v4/letter/m/22d042/32.png) [@MarcoIT](https://blenderartists.org/u/MarcoIT)\
**Post date:** [December 25, 2012, 11:33pm UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/5 "2012-12-25T23:33:01Z")

</div>

Well, I do not necessarily want to override the method.  
I asked this because I thought it was the orthodox way.

if it gives problems, no.

What do you think,of my method ? this is a correct way?  
or it can cause problems?

```auto

import bge

########################
def Update1(self):
    self.val += 0.1
    if self.val &gt; 10.0 :
        self.state = 2
        
def Update2(self):
    self.val -= 0.1
    if self.val &lt; 0.0 :
        self.state = 1
########################

class Base:
    def __init__ (self,own):
        self.owner = own
        self.val = 0.0
        self.state = 1
        
        self.stateDict = { 1: Update1, 
                            2: Update2}
        
    def Main(self):
        self.Debug()
        self.Update()
        
    def Update(self):
        #self.Update = Update1
        self.stateDict[self.state](self)
        
    def Debug(self):
        self.owner["prop"] = self.val
        
        
        
def main(cont):
    own = cont.owner
    
    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)
        
        
    own["class"].Main()

```

---

<div class="post-metadata">

**Author:** ![agoose77](https://blenderartists.org/user_avatar/blenderartists.org/agoose77/32/442949_2.png) [@agoose77](https://blenderartists.org/u/agoose77)\
**Post date:** [December 26, 2012, 3:31am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/6 "2012-12-26T03:31:37Z")

</div>

It’s not orthodox; I can’t even see what you’re trying to do. Are you attempting to do class inheritance?

---

<div class="post-metadata">

**Author:** ![sevi](https://blenderartists.org/letter_avatar_proxy/v4/letter/s/c67d28/32.png) [@sevi](https://blenderartists.org/u/sevi)\
**Post date:** [December 26, 2012, 5:45am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/7 "2012-12-26T05:45:33Z")

</div>

> class inheritance

i guess agoose77 got the point.  
Sometimes i get the same Problem, classes are getting too big, and then not easy to overview… one can always use inheritance:  
Example:

```auto
 
import bge

# (probably running) pseudo code, not testet

class BaseProperties():
    def __init__ (self, own):
        self.owner = own
        self.val = 0.0
        self.state = 1

        self.stateDict = { 1: Update1,
                            2: Update2}
class BaseFuncions():
    def __init__ (self):
        pass

    def Update1(self):
        self.val += 0.1
        if self.val &gt; 10.0 :
            self.state = 2

    def Update2(self):
        self.val -= 0.1
        if self.val &lt; 0.0 :
            self.state = 1

class Base(BaseProperties,BaseFunctions):
    def __init__ (self,own):
        # you will probably need to instanciate inherited classes...
        BaseFunctions. __init__ (self)
        BaseProperties. __init__ (self, own)

    def Main(self):
        self.Debug()
        self.Update()

    def Update(self):
        #self.Update = Update1
        self.stateDict[self.state](self)

    def Debug(self):
        self.owner["prop"] = self.val

def main(cont):
    own = cont.owner

    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)

    own["class"].Main()

```

---

<div class="post-metadata">

**Author:** ![agoose77](https://blenderartists.org/user_avatar/blenderartists.org/agoose77/32/442949_2.png) [@agoose77](https://blenderartists.org/u/agoose77)\
**Post date:** [December 31, 2012, 6:24am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/8 "2012-12-31T06:24:56Z")

</div>

I’m afraid that I don’t understand what you’re asking. Could you post in your native language as well? A lot of idioms and other expressions are lost in translation.

Here is an example of a state machine which is what you seem to be looking for

```auto

class StateMachine:
    def __init__ (self):
        self.states = {}
        self.transitions = {}
        self.current_state = ""
        
    def add_state(self, state_id, state_action=None):
        self.states[state_id] = state_action
    
    def add_transition(self, state_from, state_to, condition, action=None):
        self.transitions[state_from] = [state_to, condition, action]
    
    def update(self):
        current_state = self.current_state
                
        # Test for transitions    
        if current_state in self.transitions:
            target, condition, action = self.transitions[current_state]
            if contition. __call__ ():
                self.current_state = target
                current_state = target
                action. __call__ ()
        
        # Update state actions
        if current_state in self.states:
            state_action = self.states[current_state]
            if callable(state_action):
                state_action. __call__ ()

```

---

<div class="post-metadata">

**Author:** ![MarcoIT](https://blenderartists.org/letter_avatar_proxy/v4/letter/m/22d042/32.png) [@MarcoIT](https://blenderartists.org/u/MarcoIT)\
**Post date:** [January 2, 2013, 9:49am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/9 "2013-01-02T09:49:15Z")

</div>

yes agoose77 , it is -PROBABLY- , what I ask .(at least as alternative)  
anyway i have some trouble to get how it work . (\>function. **call** ()\< is necessary? or is the same as \>function()\< ?? )

someone can make a -simple- example switching between 2 or 3 states?

(something also with a simple float )

Thanks (PS: should be readable this post…😉 )

---

<div class="post-metadata">

**Author:** ![agoose77](https://blenderartists.org/user_avatar/blenderartists.org/agoose77/32/442949_2.png) [@agoose77](https://blenderartists.org/u/agoose77)\
**Post date:** [January 2, 2013, 10:13am UTC](https://blenderartists.org/t/how-expand-a-huge-class-in-other-script/560450/10 "2013-01-02T10:13:46Z")

</div>

You can use **call** () or just parenthesis, but I prefer call as it is more explicit.

Example:

```auto

class BasicMachine(StateMachine):
    def __init__ (self):
        super(). __init__ ()
        
        self.add_state("walk", self.walk)
        self.add_state("static", self.static)
        self.add_state("run", self.run)
        
        self.position = type(FakeVector, (), dict(x=0.0,y=0.0,z=0.0)) 
        self.velocity = type(FakeVector, (), dict(x=1.0,y=1.0,z=1.0)) 
        
    def set_state(self, state):
        self.current_state = state
        
    def walk(self):
        self.velocity.y = 0.1
        
    def run(self):
        self.velocity.y = 0.2
        
    def static(self):
        self.velocity.z = 0.05
        
    def move(self):
        self.position.y += self.velocity.y
        self.position.x += self.velocity.x
        self.position.z += self.velocity.z
        
        self.velocity.x = 0.0
        self.velocity.y = 0.0
        self.velocity.z = 0.0

class TestMachine(StateMachine):
    def __init__ (self):
        super(). __init__ ()
        
        self.add_state("walk", self.walk)
        self.add_state("static", self.static)
        self.add_state("run", self.run)
        
        self.add_transition(walk, static, self.is_static)
        self.add_transition(walk, run, self.is_running)
        self.add_transition(static, run, self.is_running)
        self.add_transition(static, walk, self.is_walking)
        self.add_transition(run, walk, self.is_walking)
        self.add_transition(run, static, self.is_static)
        
        self.position = type(FakeVector, (), dict(x=0.0,y=0.0,z=0.0)) 
        self.velocity = type(FakeVector, (), dict(x=1.0,y=1.0,z=1.0)) 
        
        self._state = None
        
    def set_state(self, state):
        self._state = state
        
    def is_static(self):
        return self._state == "Static"
    
    def is_running(self):
        return self._state == "Running"
    
    def is_walking(self):
        return self._state == "Walking"
    
    def walk(self):
        self.velocity.y = 0.1
        
    def run(self):
        self.velocity.y = 0.2
        
    def static(self):
        self.velocity.z = 0.05
        
    def move(self):
        self.position.y += self.velocity.y
        self.position.x += self.velocity.x
        self.position.z += self.velocity.z
        
        self.velocity.x = 0.0
        self.velocity.y = 0.0
        self.velocity.z = 0.0

```

The second example is basically the first example. You don’t need to do the tests because you can just set the state yourself, but the point is that you can use custom conditions for transitions.
