NameError: global name 'MyClass' is not defined in Pepper/Nao

1.1k Views Asked by At

Update: to work around the combination of Choregraphe and Python, I rejected the idea of having @classmethod. Instead I raise AlMemory events in MyCustomClass when I want to make use of MyClass.

I read many posts on NameError but still couldn't find a solution to my problem.

I write a program with Choregraphe using the Python box for Nao.

I got the followings:

class MyClass(GeneratedClass): #GeneratedClass is given

 def __init__(self):
    GeneratedClass.__init__(self)

 @classmethod
 def doSomething(cls, a):
    print a

class myCustomClass():
 def func(self):
    MyClass.doSomething(a)

When calling func() from myCustomClass, I got NameError on MyClass.

[ERROR] behavior.box :FMBox::createPythonModule:0 _Behavior__lastUploadedChoregrapheBehaviorbehavior_1275012824__root__test_1: User class evaluation failed with the error: global name 'MyClass' is not defined

How can I fix that?

2

There are 2 best solutions below

5
On

As a start your @method and class structure is wrong.

When I ran your code it says this :

class MyClass(GeneratedClass):

 @classmethod
 def do(self, a):
     return a

class myCustomClass():
 def func(self):
    MyClass.do(a)

Output:

Traceback (most recent call last):
  File "test.py", line 236, in <module>
    class MyClass(GeneratedClass):
NameError: name 'GeneratedClass' is not defined

Your class structure is completely wrong. If you want to pass a parameter, use __init__ method.

class MyClass:
    def __init__(self, GeneratedClass):
        self.generated_class = GeneratedClass

     def do(self):
         doSomething(self.generated_class)

class MyCustomClass:
    def func(self):
        GeneratedClass = 1
        MyClass(GeneratedClass).do()

myCustomClass().func()

If you are using @methodclass you should not pass self, it is cls. Like in this example:

from datetime import date

# random Person
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def fromBirthYear(cls, name, birthYear):
        return cls(name, date.today().year - birthYear)

    def display(self):
        print(self.name + "'s age is: " + str(self.age))

person = Person('Adam', 19)
person.display()

person1 = Person.fromBirthYear('John',  1985)
person1.display()

In case if you are trying inheritance take this is an example how it should be.

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

Now all in one according to yours:

class GeneratedClass:
    def __init__(self):
        self.myclass = self

    def print(self):
        print('hello_people')

class MyClass(GeneratedClass):

    def __init__(self,a):
        self.a = a
        GeneratedClass.__init__(self)
        print(a)

    @classmethod
    def give_param(cls, a):
        return cls(a)

class myCustomClass:
    def func(self):
        MyClass.give_param('aa')

myCustomClass().func()

NOTE: I have used python 3.x.

0
On

I think "MyClass" is replaced on the fly by the Choregraphe/PythonBridge interpreter invoked when you press run.

As you can see each choregraphe box classes are named "MyClass", they are so replaced and changed by a generated name like root/class/boxname...

You could try calling and printing the self.getName() in MyClass, to have a clue.

So in your case, you could:

  1. add doSomething directly in myClass
  2. create a not postprocessed, eg:

as:

class MyVeryOneClass:
 def __init__(self):
    ...