Page 1 of 1

Unbound method in class

Posted: Tue May 05, 2020 12:22 pm
by lovebby
So I'm trying to define a map here with this class:

Code: Select all

    class MAP(object):
        def __init__ (self, a_a, a_b,):
            self.a_a = [1,1]
            self.a_b = [1,2]


        def pos(self):
            self.pos = current_pos
And this is the test code I'm trying:

Code: Select all

    
    $current_pos = [1,2]
    "I'm at [MAP.pos]"
    $current_pos = [2,2]
    "Now we're at [MAP.pos]"
But I keep getting this when the game loads,

<unbound met hod MAP.pos>

and I'm not sure what unbond method is, I'm trying to make it a list and I'm assuming that's wrong?

Re: Unbound method in class

Posted: Tue May 05, 2020 12:30 pm
by rames44
There are multiple things wrong with your code. The “using it” part should more like

Code: Select all

$ current_pos = MAP(1,2)

“I’m at [current_pos.pos()]”
Although I’m not sure, off the top of my head, whether method calls work inside Ren’py interpolations.

But the class definition isn’t functional either.

I’d suggest an introductory Python class before you go too far.

Re: Unbound method in class

Posted: Tue May 05, 2020 9:05 pm
by lovebby
Yeah I've tried a python class but it's been a while and I kind of struggled am trying to pick it up again haha.

I'm not sure if themethod you posted worked fully because it just changed the text that shows. Maybe I should try a different approach but I'm not sure where?

Re: Unbound method in class

Posted: Tue May 05, 2020 9:44 pm
by hell_oh_world
lovebby wrote:
Tue May 05, 2020 9:05 pm
Yeah I've tried a python class but it's been a while and I kind of struggled am trying to pick it up again haha.

I'm not sure if themethod you posted worked fully because it just changed the text that shows. Maybe I should try a different approach but I'm not sure where?
Here's the thing, if you're familiar with programming then for sure you're familiar with object-oriented programming? If not, then lemme explain it to you in a short note. Typically, what you did was a class, or what you call a blueprint for objects. Objects are just instances of a class. Now going into your code, you did `MAP.pos`. This is not wrong, unfortunately, you're referencing directly on the class rather than on an instance of that class.

Code: Select all

init python:
	class MAP:
		pos = 0.5 # a class attribute. Class attributes are declared outside the constructor and functions.
		
		def __init__(self): # the constructor, this is where you initialized variables and things...
			self.loc = (0, 1) # an object attribute, this is only accessible by the instance

default map = MAP() # an instance of the class (an object)
default map2 = MAP() # another instance

label start:
	"[MAP.pos]" # this will work, as pos is a class attribute and you're referencing the MAP  class instead of the object
	"[map.pos]" # this will also work as an object has both access in class attributes and object attributes
	"[MAP.loc]" # won't work, since only an instance has access to object attributes
	"[map.loc]" # will work as loc is an object attribute and map is an object
The above code works because the `pos` is a property or what you call a `class attribute` rather than an `object attribute`. Object attributes are those attributes that you simply defined inside the constructor using the know format `self.attribute`. Just remember this: A class has access to its class attributes but not on its object attributes, an object, on the other hand, has access to both. Be reminded also that class attributes are shared across all instances, that once you modify it on once instance, it will apply on the other too.
So doing...

Code: Select all

label start:
	$ map.loc = 1.0
	"[map.loc]" # 1.0
	"[map2.loc]" # 1.0
Editing a class attribute applies across all instances of that class.
One last thing, if you have functions that return something, i suggest not interpolating it directly, but assigning the return value first then interpolate that variable instead.

Code: Select all

label start:
	$ val = object.function_that_returns_something()
	"The returned value is [val]"

Re: Unbound method in class

Posted: Tue May 05, 2020 9:48 pm
by MaydohMaydoh
If you want to get a value from a method, the method needs to return a value. Currently your method only sets the attribute. Also the attribute has the name of the method and also doesn't exist? Also the arguments that are being passed to the class object are doing nothing, unless you have it set like that for debugging.

I believe it should be something like

Code: Select all

class MAP(object):
    def __init__(self, a_a, a_b):
        self.a_a = a_a
        self.a_b = a_b
        self._pos = [0, 0]
   
   @property
   def pos(self):
       return self._pos
       
   @pos.setter
   def pos(self, new):
       self._pos = new
Edit: This calls from an object rather than the class itself which hell_oh_world explained above.

Re: Unbound method in class

Posted: Thu May 07, 2020 5:08 pm
by gas
MaydohMaydoh wrote:
Tue May 05, 2020 9:48 pm

I believe it should be something like

Code: Select all

   @property
   def pos(self):
       return self._pos
Why @property? You can actually retrieve the property directly and change it at runtime. Isn't that redundant? Genuinely asking.