0

I know I'm just missing something simple here. I looked through other answers but couldn't find this problem.

>>> class Ben:
... """Can access variable but not method"""
... i = 320894
... def foo(self):
... return i
... 
>>> Ben.i
320894
>>> Ben.foo(self)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'self' is not defined
asked Jul 25, 2013 at 19:15
1
  • 6
    You should read the Python tutorial to familiarize yourself with the basics of classes in Python. Commented Jul 25, 2013 at 19:16

4 Answers 4

4

You don't pass self yourself. It is a reference to an instance of the class on which you invoke that method. So, you would need to create an instance of Ben, and invoke that method on that instance:

ben = Ben()
ben.foo()

And instead of:

return i 

you need to use:

return self.i
answered Jul 25, 2013 at 19:16
Sign up to request clarification or add additional context in comments.

1 Comment

You should point out that the class atribute of i is being returned solely because the instance attribute i does not exist in the OP example. If you want unambiguously to have the class value of i you should use return self.__class__.i otherwise the instance value is returned if it exists.
3

You need to instantiate a class instance in this case and invoke the method from that.

>>> class Ben:
 """Can access variable but not method"""
 i = 320894
 def foo(self):
 return self.i
>>> a = Ben()
>>> a.foo()
320894

P.S - You don't pass self as an argument and you have to change the return statement to self.i.

answered Jul 25, 2013 at 19:15

Comments

3

You first must create an instance of the class. "self" is automatically added as the first parameter, you can't pass it in yourself.

ben = Ben()
ben.foo()
answered Jul 25, 2013 at 19:15

Comments

1

Here are the various way I can think of (off the top 'o my head) to get a class attribute from an instance method:

class Ben:
 i = 320894
 def foo(self):
 return self.i, self.__class__.i, Ben.i, Ben.__dict__['i'], getattr(Ben,'i')
print Ben().foo() 

Prints:

(320894, 320894, 320894, 320894, 320894)

Note the Ben().foo() vs Ben.foo(self) -- You need an instance of Ben prior to calling foo and self is implicit in the calling of foo as a method of that instance. If you have Ben().foo() the instance is created similarly to b=Ben() and then calling b.foo()

self.i or Ben.i is the most straightforward. Keep in mind that these can be different i's. self.i is an instance attribute and Ben.i is a class attribute:

class Ben(object):
 i = 'class i'
 def __init__(self):
 self.i='instance i'
 def foo(self):
 return ('Instance i:',self.i, getattr(self,'i'), self.__dict__['i'],
 'Class i:',self.__class__.i, getattr(Ben,'i'), Ben.i, Ben.__dict__['i'])
print Ben().foo() 

Prints:

('Instance i:', 'instance i', 'instance i', 'instance i', 
 'Class i:', 'class i', 'class i', 'class i', 'class i')
answered Jul 25, 2013 at 19:47

4 Comments

This bypasses the OP's real problem, which was not understanding the need to create an instance (and that self was an implicit argument passed to the method when invoked by an instance).
I understand that. Since he had three answer that stated the same thing, I thought I would post an answer that showed actually the difference between a class attribute and an instance attribute of the same name.
@chepner: I added you helpful comments to the text. Thanks!
+1 for pointing out the difference between class and instance attributes (speaking from personal experience with a subtle bug...)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.