开发者

Python instance has no __call__ method

I've been learning how to use Python for the better part of today after giving up on an ugly bash script.

I'm trying to use 2 classes to define a few arrays of objects in which to store some unique strings and integers (1-10). The objects will consist of the following:

object[i].user
         .n     # n = i
         .name
         .coords
         .hero

(param1, param2, param3) will be different for each object.n and object.user, so I'm trying to use an assignment method that doesn't look like garbage after writing 90 unique strings. Nesting an example I found didn't work, so here's the compromise:

class CityBean:
    def __init__(self,name,coords,hero):
        self.nam开发者_开发技巧e = name
        self.coords = coords
        self.hero = hero

class Castles:
    def __init__(self,user,n):
        self.user = user
        self.n = n
        if self.user == 'user1':
            temp = {
                1:  CityBean( "name1"  , "coord1" , "hero1"),
                ... blah blah blah
                10: CityBean( "name10" , "coord10" , "hero10" )}[self.n]()
        if self.user == 'user2':
            temp = {
                1:  CityBean( "name11" , "coord11" , "hero11" ),
                ... blah blah blah
                10: CityBean( "name20" , "coord20" , "hero20" ) }[self.n]()
        if self.user == 'user3':
            temp = {
                1:  CityBean( "name21" , "coord21" , "hero21" ),
                ... blah blah blah
                10: CityBean( "name30" , "coord30" , "hero30" ) }[self.n]()
        self.name = temp.name
        self.coords = temp.coords
        self.hero = temp.coords
        __del__(temp)

I call it with something like this:

cities = list( Castles("user2",i) for i in range(1,11) )

It gives me this error:

AttributeError: CityBean instance has no __call__ method

And it blames this line:

                10: CityBean( "name20" , "coord20" , "hero20" ) }[self.n]() # pseudo
                10: CityBean( "" , "" , "" ) }[self.n]() # what is actually looks like

What's wrong with my cruddy classes? I'm doing something retarded, aren't I?


It's really hard to guess what you want from what you provided, since, instead of saying what you want to do, you provided your newbie code, so one has a hard guess time.

I'd think something like this would do:

data = {
        (1, 'user1'): ("name1", "coord1", "hero1"),
        (2, 'user1'): ("name2", "coord2", "hero2"),
        #...
        (1, 'user2'): ("name11", "coord11", "hero11"),
        (2, 'user2'): ("name12", "coord12", "hero12"),
        # ...
    }


class CityBean:
    def __init__(self,name,coords,hero):
        self.name = name
        self.coords = coords
        self.hero = hero

class Castles:
    def __init__(self,user,n):
        self.user = user
        self.n = n
        name, coords, hero = data.get((n, user))
        self.citybean = CityBean(name, coords, hero)


Why did your write this?

temp = {
            1:  CityBean( "name21" , "coord21" , "hero21" ),
            ... blah blah blah
            10: CityBean( "name30" , "coord30" , "hero30" ) }[self.n]()

What do you think temp= {...}[something]() will do?

  1. It creates a dictionary. {...}

  2. It picks one item out of the dictionary. {...}[something]. This will be a CityBean object.

  3. It evaluates that one item as a function {...}[something]() Is CityBean(...)()

Why are you calling the CityBean object as if it was a function?

Further, why are you creating entire dictionaries only to pick a single item of it? What's wrong with if statements?


your are doing

{
1:  CityBean( "name1"  , "coord1" , "hero1"),
... blah blah blah
10: CityBean( "name10" , "coord10" , "hero10" )}[self.n]()

which is basically from a dict get value based on key, values on your dict are CityBean instances, so in short you are doing this

CityBean( "name1"  , "coord1" , "hero1")()

which is valid but will call the special method __call__ of the instance, so either remove () or add a __call__ method depending on the need


I don't really understand what you're trying to do exactly, but:

 10: CityBean( "name10" , "coord10" , "hero10" )}[self.n]()

if calling something (the () at the end make it a function call).

What you would want is I think temp = { ... 10: CityBean( "name10" , "coord10" , "hero10" )}[self.n]

In that case you'd get the dict entry with key n and label that temp.


Notice, that in python, when you write

CityBean( "name1"  , "coord1" , "hero1")

You initialize the object CityBean. There is no need for an extra ().


You can get this problem if you do something wrong

os.environ("METAG_DATA")

The correct way is

os.environ["METAG_DATA"]


Putting parens after a class name in a normal expression instantiates it immediately. If you want to delay instantiation then you'll need to use lambda or functools.partial():

10: lambda: CityBean("", "", "")}...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜