problem with str()

7

7stud

I can't get the str() method to work in the following code(the last
line produces an error):

============
class test:
"""class test"""
def __init__(self):
"""I am init func!"""
self.num = 10
self.num2 = 20
def someFunc(self):
"""I am someFunc in test!"""
print "hello"


obj = test()
obj.someFunc()
names = dir(obj)
print names

methodList = [str for str in names if callable(getattr(obj, str))]
print methodList

x = getattr(obj, methodList[0]).__doc__
print x
print type(x)
print str(getattr(obj, methodList[0]).__doc__)
===========

Here is the output:

$ python test1.py
hello
['__doc__', '__init__', '__module__', 'num', 'num2', 'someFunc']
['__init__', 'someFunc']
I am init func!
<type 'str'>
Traceback (most recent call last):
File "test1.py", line 23, in ?
print str(getattr(obj, methodList[0]).__doc__)
TypeError: 'str' object is not callable

This is part of some code in Diving Into Python,Chapter 4. In case a
function doesn't have a __doc__ string, and therefore __doc__ returns
None, the code needs to convert each __doc__ to a string so that the
result is guaranteed to be a string.
 
L

Larry Bates

7stud said:
I can't get the str() method to work in the following code(the last
line produces an error):

============
class test:
"""class test"""
def __init__(self):
"""I am init func!"""
self.num = 10
self.num2 = 20
def someFunc(self):
"""I am someFunc in test!"""
print "hello"


obj = test()
obj.someFunc()
names = dir(obj)
print names

methodList = [str for str in names if callable(getattr(obj, str))]
print methodList

x = getattr(obj, methodList[0]).__doc__
print x
print type(x)
print str(getattr(obj, methodList[0]).__doc__)
===========

Here is the output:

$ python test1.py
hello
['__doc__', '__init__', '__module__', 'num', 'num2', 'someFunc']
['__init__', 'someFunc']
I am init func!
<type 'str'>
Traceback (most recent call last):
File "test1.py", line 23, in ?
print str(getattr(obj, methodList[0]).__doc__)
TypeError: 'str' object is not callable

This is part of some code in Diving Into Python,Chapter 4. In case a
function doesn't have a __doc__ string, and therefore __doc__ returns
None, the code needs to convert each __doc__ to a string so that the
result is guaranteed to be a string.

You masked the built-in str method in your list comprehension.

Try changing to:

methodList = [s for s in names if callable(getattr(obj, str))]

I'll bet it will work then.

-Larry
 
K

kyosohma

I can't get the str() method to work in the following code(the last
line produces an error):

============
class test:
"""class test"""
def __init__(self):
"""I am init func!"""
self.num = 10
self.num2 = 20
def someFunc(self):
"""I am someFunc in test!"""
print "hello"

obj = test()
obj.someFunc()
names = dir(obj)
print names

methodList = [str for str in names if callable(getattr(obj, str))]
print methodList

x = getattr(obj, methodList[0]).__doc__
print x
print type(x)
print str(getattr(obj, methodList[0]).__doc__)
===========

Here is the output:

$ python test1.py
hello
['__doc__', '__init__', '__module__', 'num', 'num2', 'someFunc']
['__init__', 'someFunc']
I am init func!
<type 'str'>
Traceback (most recent call last):
File "test1.py", line 23, in ?
print str(getattr(obj, methodList[0]).__doc__)
TypeError: 'str' object is not callable

This is part of some code in Diving Into Python,Chapter 4. In case a
function doesn't have a __doc__ string, and therefore __doc__ returns
None, the code needs to convert each __doc__ to a string so that the
result is guaranteed to be a string.

Your string comprehension over wrote the str built-in method, turning
it into a variable. If you just type "str" (without the quotes) into
the interpreter, it'll spit out 'someFunc'. Thus, you cannot use str
as the iterator in your code:

methodList = [str for str in names if callable(getattr(obj, str))]

instead, do something like this:

methodList = [i for i in names if callable(getattr(obj, i))]

Have fun!

Mike
 
T

Terry Reedy

|I can't get the str() method to work in the following code(the last
| line produces an error):

If you 'print str' here

| methodList = [str for str in names if callable(getattr(obj, str))]

and again here, you will see the problem; you have reassigned the name
'str' to something else by using it in the list comp. Hence the advice to
never reuse
builtin names unless you mean to lose access to the builtin object.

|print str(getattr(obj, methodList[0]).__doc__)

Here I presume you want the builtin function. Too bad... ;-)

Terry Jan Reedy
 
7

7stud

Sheesh! You would think that after looking at every inch of the code
for way too many hours, at some point that would have poked me in the
eye.

Thanks all.
 
S

Steve Holden

7stud said:
Sheesh! You would think that after looking at every inch of the code
for way too many hours, at some point that would have poked me in the
eye.

Thanks all.
Get yourself a stuffed bear, and next time you have this kind of problem
spend a few minutes explaining to the bear exactly how your program
can't possibly be wrong. Works like a charm.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Blog of Note: http://holdenweb.blogspot.com
See you at PyCon? http://us.pycon.org/TX2007
 
G

Gabriel Genellina

methodList = [str for str in names if callable(getattr(obj, str))]

instead, do something like this:

methodList = [i for i in names if callable(getattr(obj, i))]

The fact that a list comprehension "leaks" its variables into the
containing scope is a bit weird.
A generator expression doesn't:

py> str
<type 'str'>
py> w = (str for str in range(10))
py> w
<generator object at 0x00AD7C38>
py> str
<type 'str'>
py> w.next()
0
py> str
<type 'str'>
 
P

Paul Rubin

methodList = [str for str in names if callable(getattr(obj, str))]

instead, do something like this:

methodList = [i for i in names if callable(getattr(obj, i))]

or:

methodList = list(str for str in names if callable(getattr(obj, str)))

genexps, unlike listcomps, make a new scope for their index variable.
 
A

Alex Martelli

Steve Holden said:
Get yourself a stuffed bear, and next time you have this kind of problem
spend a few minutes explaining to the bear exactly how your program
can't possibly be wrong. Works like a charm.

A rubber ducky works much better for that, btw -- more easily washable
than a stuffed bear, for example.


Alex
 
S

Steve Holden

7

7stud

The fact that a list comprehension "leaks" its variables into the
containing scope is a bit weird.
A generator expression doesn't:

py> str
<type 'str'>
py> w = (str for str in range(10))
py> w
<generator object at 0x00AD7C38>
py> str
<type 'str'>
py> w.next()
0
py> str
<type 'str'>

or:

methodList = list(str for str in names if callable(getattr(obj, str)))

genexps, unlike listcomps, make a new scope for their index variable.


Thanks.
 
A

Alex Martelli

Steve Holden said:
But stuffed bears are so much more knowledgeable about the minutiae of
software design.

And yet, the key to Python's strength is duck typing -- if you can teach
the duck to type, you've got it made.


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top