title: exec to add a function into a class
body: <p>So I've looked at similar questions, and I've found some solutions to this, but I can't quite figure out how to do this. </p>
  
  <p>What I'm trying to do is add a method to a class from a string. I can do this with the <code>setattr()</code> method, but that won't let me use <code>self</code> as an attribute in the extra method. Here's an example: (and I apologize for the variable names, I always use yolo when I'm mocking up an idea)</p>
  
  <pre><code>class what:
      def __init__(self):
          s = 'def yolo(self):\n\tself.extra = "Hello"\n\tprint self.extra'
          exec(s)
          setattr(self,"yolo",yolo)
  
  what().yolo()
  </code></pre>
  
  <p>returns this:</p>
  
  <pre><code>Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  TypeError: yolo() takes exactly 1 argument (0 given)
  </code></pre>
  
  <p>and if <code>s = 'def yolo():\n\tself.extra = "Hello"\n\tprint self.extra'</code>
  then I get this result:</p>
  
  <pre><code>Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
    File "&lt;string&gt;", line 2, in yolo
  NameError: global name 'self' is not defined
  </code></pre>
  
  <p>This essentially means that I cannot dynamically create methods for classes, which I know is bad practice and unpythonic, because the methods would be unable to access the variables that the rest of the class has access to. </p>
  
  <p>I appreciate any help.</p>