1

I have two files. In the first there is a dictionary ready for export:

__all__ = ['container']

def show_name(self):
   myFunction()
   print self.name

container = {
   'show_name': show_name
}

In the second file I import myFunction and I define the class Person:

from myModule import myFunction

class Person:
   def __init__(self):
      self.name = 'Bob'
      self.show_name = types.MethodType(container['show_name'], self)

person = Person()

The problem is that when I call person.show_name() I get the error:

NameError: global name 'myFunction' is not defined

How can I have Person.show_name access the same functions Person does?

Randomblue
  • 112,777
  • 145
  • 353
  • 547
  • 1
    where is myFunction() defined? – soulcheck Jan 18 '12 at 14:16
  • I think you meant `container` where you wrote `display`. – Fred Foo Jan 18 '12 at 14:18
  • I've got a feeling that the root of the woes in your recent questions is a design problem. We can show you ways how to overcome the symptoms of this design problem, but we can't fix the real issue since we don't know enough about the system. It is possible to create a new function object from `f = container['show_name']` with access to the current globals using `types.FunctionType(f.__code__, globals(), f.__name__, f.__defaults__)`; I don't think this hack would solve the actual problem though, so I'm not posting it as an answer. – Sven Marnach Jan 18 '12 at 15:17
  • 1
    @SvenMarnach: You are most probably right! The design problem was that I was not using mixins and class inheritance. Slowly but surely I'm getting the hang of Python. – Randomblue Jan 18 '12 at 16:29

1 Answers1

2

Move from myModule import myFunction to the same file where show_name is defined.


By the way,

class Person:
   def __init__(self):
      self.name = 'Bob'
      self.show_name = types.MethodType(container['show_name'], self)

makes ('show_name',<bound_method>) a key-value pair in self.__dict__. That causes every instance of Person to get a new, independent key-value pair.

To save memory, you might want to change that to Roman Bodnarchuk other solution.

class Person:
   show_name = container['show_name']
   def __init__(self):
      self.name = 'Bob'
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • I cannot do that because of an infite `import` loop problem, and because person needs `myFunction` also. Is there another solution to ensure closure? – Randomblue Jan 18 '12 at 14:21
  • @Randomblue: you could pass `myFunction` to `show_name` as an argument. – Fred Foo Jan 18 '12 at 14:23
  • @Randomblue: You could do as larsmans suggests, or refactor `myModule` so you could import the right code without any import problems. – unutbu Jan 18 '12 at 14:28