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?
It creates a dictionary.
{...}
It picks one item out of the dictionary.
{...}[something]
. This will be aCityBean
object.It evaluates that one item as a function
{...}[something]()
IsCityBean(...)()
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("", "", "")}...
精彩评论