[SOLVED] Class Attributes in Micropython

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
Scalli
Posts: 9
Joined: Tue Jun 12, 2018 5:37 am

[SOLVED] Class Attributes in Micropython

Post by Scalli » Thu Aug 02, 2018 12:49 pm

Hi I try to implement a Micropython C Class and I wonder if there is a posibillity, to generate a class like this:

Code: Select all

>>>class test:
>>>	testint = 10;
In C code.
I want to call it in python with

Code: Select all

>>>testvar = test()
>>>testvar.testint
10
I know the implementation of a class but not how to make a Variable callable like this.
Could somebody help me?
Thanks Scalli
Last edited by Scalli on Mon Aug 06, 2018 8:08 am, edited 1 time in total.

jickster
Posts: 547
Joined: Thu Sep 07, 2017 8:57 pm

Re: Class Attributes in Micropython

Post by jickster » Thu Aug 02, 2018 2:38 pm

Scalli wrote:
Thu Aug 02, 2018 12:49 pm
Hi I try to implement a Micropython C Class and I wonder if there is a posibillity, to generate a class like this:

Code: Select all

>>>class test:
>>>	testint = 10;
In C code.
I want to call it in python with

Code: Select all

>>>testvar = test()
>>>testvar.testint
10
I know the implementation of a class but not how to make a Variable callable like this.
Could somebody help me?
Thanks Scalli
Your example is slightly ambiguous: are you interested in class variables or instance variables?
Your "testint" is technically a class variable which means it's shared among ALL instances.
If you want an instance variable - which is unique to each instance of class test - you use "self.testint" in the "__init__" function.

Implementing instance variables
Basically, you have to implement the .attr function; take a look at "mp_type_module" as it's the simplest type.

Code: Select all

const mp_obj_type_t mp_type_module = {
    { &mp_type_type },
    .name = MP_QSTR_module,
    .print = module_print,
    .attr = module_attr,
};
and its associated C-data structure

Code: Select all

typedef struct _mp_obj_module_t {
    mp_obj_base_t base;
    mp_obj_dict_t *globals;
} mp_obj_module_t;
The "globals" here holds a ptr to dictionary which holds the instance members.

For clarity, I'll create a new type with the names you've used

Code: Select all

const mp_obj_type_t mp_type_test = {
    { &mp_type_type },
    .name = MP_QSTR_test,
    .print = test_print,
    .attr = test_attr,
    .make_new = test_make_new // THIS IS DIFFERENT FROM ABOVE
};
I added ".make_new" because you want to be able to create objects of type test; without this, you cannot say "testvar = test()".

The associated C-data structure

Code: Select all

typedef struct _mp_obj_test_t {
    mp_obj_base_t base;
    mp_obj_dict_t *globals;
} mp_obj_test_t;
Nothing is different here.

I'm not going to write EVERY single-line necessary, just what is critical.
Use objlist.c as a guide because it includes a ".make_new"

Code: Select all

STATIC mp_obj_t test_make_new (const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) 
{
(void)type_in;
mp_arg_check_num(n_args, n_kw, 0, 0, false);
// Create the C-obj
mp_obj_test_t * test = m_new_obj(mp_obj_test_t);
// Set the base
test->base.type = &mp_type_test;
// Create the dictionary to hold instance variables
test->globals = MP_OBJ_TO_PTR(mp_obj_new_dict(0));

// Now add the members one by one
mp_obj_dict_store(MP_OBJ_FROM_PTR(test ->globals), MP_OBJ_NEW_QSTR(MP_QSTR_testint), MP_OBJ_NEW_SMALL_INT(0));

return MP_OBJ_FROM_PTR(test);
}
Now you have ability to create a new object of type "test".

To be able to modify "testint" member, you have to add the ".attr = test_attr" function; look at "module_attr" for a guide.
The ".attr" function is used for 3 different operations:
1) store: testvar.testint = 55
2) load: b = testvar.testint
3) delete: del testvar.testint

Depending on your class, you may want to disallow aka fail on none or some of these operations.

Online
stijn
Posts: 281
Joined: Thu Apr 24, 2014 9:13 am

Re: Class Attributes in Micropython

Post by stijn » Thu Aug 02, 2018 3:35 pm

If you want a static class variable on the other hand, i.e. the equivalent of

Code: Select all

class test:
  testint = 1
  
print(test.testint)
you just have to add it to the type's locals_dict

jickster
Posts: 547
Joined: Thu Sep 07, 2017 8:57 pm

Re: Class Attributes in Micropython

Post by jickster » Thu Aug 02, 2018 3:41 pm

stijn wrote:If you want a static class variable on the other hand, i.e. the equivalent of

Code: Select all

class test:
  testint = 1
  
print(test.testint)
you just have to add it to the type's locals_dict
Yes but if you define .attr you still have to add code in .attr to read from locals_dict

Online
stijn
Posts: 281
Joined: Thu Apr 24, 2014 9:13 am

Re: Class Attributes in Micropython

Post by stijn » Thu Aug 02, 2018 4:29 pm

jickster wrote:
Thu Aug 02, 2018 3:41 pm
Yes but if you define .attr you still have to add code in .attr to read from locals_dict
Hmm, in what circumstances would .attr be called when there isn't an instance of the class yet?
At least for me loading of things stored in locals_dict goes via type_attr() and mp_obj_class_lookup().
Just like when I do dir(test) it lists testint and it can only do so because it's in locals_dict..

jickster
Posts: 547
Joined: Thu Sep 07, 2017 8:57 pm

Re: Class Attributes in Micropython

Post by jickster » Thu Aug 02, 2018 9:43 pm

stijn wrote:
Thu Aug 02, 2018 4:29 pm
Hmm, in what circumstances would .attr be called when there isn't an instance of the class yet?
It wouldn't. Didn't mean to imply that.
I meant on an instance object.
stijn wrote:
Thu Aug 02, 2018 4:29 pm
At least for me loading of things stored in locals_dict goes via type_attr() and mp_obj_class_lookup().
Yes I agree.
stijn wrote:
Thu Aug 02, 2018 4:29 pm
Just like when I do dir(test) it lists testint and it can only do so because it's in locals_dict..
For an mp_type_type, dir() only needs to look at .locals_dict but for an instance it's not enough.
If you "dir()" on an instance object AND you've defined ".attr", then in your ".attr" definition, you need to look in two different dicts: .locals_dict and the dict used to store your instance attributes. This second dict would hold values unique to an instance of the class i.e. "unique"

Code: Select all

class test:
  testint = 1
  def __init__(self, unique_int):
    self.unique = unique_int

Scalli
Posts: 9
Joined: Tue Jun 12, 2018 5:37 am

Re: Class Attributes in Micropython

Post by Scalli » Fri Aug 03, 2018 9:41 am

Im sorry.
I've ment a Instance Variable.
Thanks alot for your input.
I try it asp.

EDIT 3.8.18. 15:38:
It worked thanks alot.

jickster
Posts: 547
Joined: Thu Sep 07, 2017 8:57 pm

Re: Class Attributes in Micropython

Post by jickster » Fri Aug 03, 2018 2:58 pm

Scalli wrote:
Fri Aug 03, 2018 9:41 am
Im sorry.
I've ment a Instance Variable.
Thanks alot for your input.
I try it asp.

EDIT 3.8.18. 15:38:
It worked thanks alot.
If your issue is solved, please edit the title of the first post in this topic and prepend "[SOLVED]" to keep the forum tidy.
Thanks.

Post Reply