简体   繁体   中英

str object is not callable error python

I've been trying to run the following code in Python:

def likes(names):
    dictionary_of_sizes = {
        0:"no one likes this", 
        1:(lambda names: "{} likes this".format(names[0])),
        2:(lambda names: "{} and {} like this".format(names[0], names[1])),
        3:(lambda names: "{}, {} and {} like this".format(name[0], names[1],names[2])),
        4:(lambda names: "{}, {} and {} others like this".format(names[0], names[1], len(names)-2))
    }
    return dictionary_of_sizes[len(names)](names) if len(names)<4 else dictionary_of_sizes[4]

I always get the error 'str' object is not callable.

Question: What am I doing wrong?

If you pass an empty string it will write out you error message. You could use a list instead of the dictionary:

def likes(names):
    options = ["no one likes this", 
                lambda names: "{} likes this".format(names[0]),
                lambda names: "{} and {} like this".format(names[0], names[1]),
                lambda names: "{}, {} and {} like this".format(name[0], names[1],names[2]),
                lambda names: "{}, {} and {} others like this".format(names[0], names[1], len(names)-2)
            ]
    if type(names) == list:
        return options[min(len(options),len(names))](names)

Using Python 3.6's f-strings:

def likes(names):
    options = [ lambda:"no one likes this", 
                lambda:f"{names[0]} likes this",
                lambda:f"{names[0]} and {names[1]} like this",
                lambda:f"{names[0]}, {names[1]} and {names[2]} like this",
                lambda:f"{names[0]}, {names[1]} and {len(names)-2} others like this"
            ]
    return options[min(len(options),len(names))]()


print(likes([]))
print(likes("bob"))
print(likes([""]))
print(likes(["alice","bob"]))
print(likes(["alice","bob","charlie"]))
print(likes(["alice","bob","charlie","david"]))

Outputs:

no one likes this
no one likes this
b, o and b like this
 likes this
alice and bob like this
alice, bob and charlie like this
alice, bob and 2 others like this

You're not showing us the code that throws the exception. It's kind of hard to say what you are doing wrong, when you don't tell us what you are doing. But if I do this, it seems to work:

>>> likes(["John","Harry"])
'John and Harry like this'

I suspect you may be calling likes() like this:

>>> likes(["John","Harry"])()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'str' object is not callable

Or like this:

>>> likes("")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 7, in likes
TypeError: 'str' object is not callable

It's not surprising you are having trouble working out how to call the function. The code is unnecessarily complicated for what it does. It needs a complete rewrite. If you want a quick fix, change this line:

{0:"no one likes this", 

to

{0:(lambda names: "no one likes this"),

But you should really drop all those unnecessary and hard-to-read lambda s and do something like:

def likes(names):
    if len(names) > 3:
        names = names[:2] + [f"{len(names)-2} others"]
    elif len(names) == 0:
        names = ["no-one"]
    result = " and ".join(", ".join(names).rsplit(", ",1))
    if len(names) == 1:
        return result + " likes this"
    else:
        return result + " like this"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM