Python实例没有__call__方法

-1 投票
7 回答
16270 浏览
提问于 2025-04-15 19:34

今天我花了大部分时间在学习如何使用Python,因为我放弃了一个看起来很糟糕的bash脚本。

我想用两个类来定义一些对象数组,用来存储一些独特的字符串和整数(1到10)。这些对象会包含以下内容:

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

每个对象的(param1, param2, param3)都会不同,所以我想用一种写法来赋值,这样在写了90个独特字符串后,代码看起来不会那么糟糕。我尝试了一个嵌套的例子,但没有成功,所以我找到了一个折中的办法:

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
        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)

我用类似这样的方式来调用它:

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

结果给了我这个错误:

AttributeError: CityBean instance has no __call__ method

而且错误指向了这一行:

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

我的类到底哪里出了问题?我是不是做了什么很傻的事情?

7 个回答

2

你正在做的事情是

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

这基本上是从一个字典中根据键获取值,你的字典里的值是 CityBean 实例,简单来说,你在做的就是这个

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

这个是有效的,但会调用实例的特殊方法 __call__,所以根据需要,要么去掉 (),要么添加一个 __call__ 方法

4

你为什么要这样写呢?

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

你觉得 temp= {...}[something]() 会做什么呢?

  1. 它创建了一个字典。 {...}

  2. 它从字典中选出一个项目。 {...}[something]。这个项目会是一个 CityBean 对象。

  3. 它把这个项目当作一个函数来执行 {...}[something](),也就是 CityBean(...)()

你为什么把 CityBean 对象当成函数来调用呢?

而且,为什么要创建整个字典却只取其中的一个项目呢?用 if 语句不行吗?

6

根据你提供的信息,很难猜出你想要什么,因为你没有直接说明你的需求,而是给出了你的初学者代码,这让人很难理解。

我觉得可以试试这样的代码:

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)

撰写回答