【问题标题】:Pass the attribute from a class to another call将属性从一个类传递给另一个调用
【发布时间】:2018-08-03 09:24:34
【问题描述】:

我试图将值从getattr 传递给另一个class Map(),但它仍然告诉我引擎类中没有这个参数。问题是我如何将属性传递给类 Map?它一直在寻找class Engine() 中的属性。

class Engine(object):

    def __init__(self,start):
        self.map = start
        self.quips = [
            "You died.  You kinda suck at this.",
            "Your mom would be proud. If she were smarter.",
            "Such a luser.",
            "I have a small puppy that's better at this."            
        ]

    def death(self):
        print (self.quips[randint(0,len(self.quips) - 1)])
        exit(1)

    def play(self):
        next = self.map

        while True:
            print ("\n------------------")
            # Trying to get attribute of object and pass to class Map.
            Map = getattr(self, next)
            next = Map()


class Map():

    def __init__(self, next):
        self.map = next

    def central_corridor(self):
        print ("The Gothons of planet Percal #25 have invaded your ship and destryoed")
        if action == "shoot!":
           print ("Quick on the draw you yank out your blaster and fire)
           return 'death'
        elif action == 'tell a joke':
           print ("Lucky for you they made you learn Gothon insults in the academy")    
           return 'Go to bridge'

    def go_to_bridge(self):
        print ("You burst onto the Bridge with the neutron destruct bomb")
a_game = Engine("central_corridor")

a_game.play()

追溯

Traceback (most recent call last): File"c:\Learn_Python_In_the_hard_way\SourceCode\E42_Class_Execrise.py", line 175, in <module> a_game.play() File "c:\Learn_Python_In_the_hard_way\SourceCode\E42_Class_Execrise.py", line 27, in play Map = getattr(self, next) AttributeError: 'Engine' object has no attribute 'central_corridor'

【问题讨论】:

  • 您遇到的错误的完整追溯是什么?我猜它与next = Map() 有关,您尝试在没有参数的情况下初始化Map,但需要next 参数。
  • 您在代码中哪里看到了getattr() 调用?如果您需要任何帮助,请发布正确的 MCVE 和完整的错误消息和回溯。
  • 对不起,我把我的另一个版本放在这里。我又更新了。
  • 您的代码中有很多错误,您没有在此处关闭字符串: print ("Quick on draw you yank out your blaster and fire),play 方法写得不好,您应该重新考虑你的代码有点。
  • 好的,你需要决定你存储玩家位置的位置(大概是地图中的状态变量,而不是引擎)。 1) Engine class 不需要知道玩家在哪里,只要他们是活着还是死了(他们携带什么,他们的能量水平是多少,得分等)。所以尝试用Engine("central_corridor") 初始化东西是没有意义的。 Engine 类不需要知道如何 来初始化Map 的实例。 2) 那么如何编写Map 类,使其自身将其位置初始化为“central_corridor”? 2b)位置应该存储为数据成员,而不是方法

标签: python adventure


【解决方案1】:

以下是您需要解决的分解问题:

  • 您应该将玩家的位置作为状态变量存储在Map,而不是Engine。实际上,您应该将 Map 重命名为 Location,因为它不仅仅记录它们的位置,它还知道哪些操作是合法的并对其进行处理,然后更新到新位置。
  • Engine class 不需要知道玩家在哪里,只需要知道他们是死是活(他们携带什么、他们的能量水平、得分等)。
  • 所以尝试初始化Engine("central_corridor") 是没有意义的。 (顺便说一句,“central_corridor”是一个字符串,Map.central_corridor 是一个方法,但是这样做仍然会很糟糕,你会无缘无故地将引擎耦合到地图)
  • Engine 类应该不需要知道如何初始化 Map 的实例
  • 那么如何编写Map 类,使其自行将其位置初始化为“central_corridor”?

    • 位置应存储为数据成员(Map 中的方法应设置或获取self.location = "central corridor", "bridge"),而不是作为方法Map.central_corridor()Map.go_to_bridge()。当然,如果您这样做,您需要为每个合法的源-目的地对位置使用一种方法,除非冒险非常线性,否则这将是不必要的。
  • 所以您目前的想法是将位置存储为来自Map 的方法名称,然后让Engine.play() 循环遍历这些位置(方法名称)。

  • Engine.play 只是让您头疼地从 Map Engine 和合法通过的位置传递控制流
  • 还有action 来自哪里?您缺少一种要求玩家采取行动并拒绝并循环的方法,除非它识别出该位置的合法行动。
  • 并考虑Map 类应该如何将状态(活/死)传递回Engine。作为字符串?作为布尔值?或者您可以返回None 以表明玩家已经死亡?
  • 那么解决方案是什么样的呢?
    • Map 重命名为Location
    • Location 将有一个成员 where(或 state 或任何您想称呼的名称)
    • EngineEngine.__init__ 只需要定义 self.location = Location()。初始状态不通过。
  • Location 类应该有一个大方法 turn(),它检查 self.location 的当前值,打印任何相应的描述文本,调用一个方法来获取玩家行为(可能希望将合法行为列表作为字符串传递给它),然后处理为该位置选择的动作,并确定下一个动作和下一个玩家状态(活着/死去)。

【讨论】:

  • 感谢 smci。我按照你说的重建了程序。很明显,我发现我完全不理解“类”功能,这个问题太愚蠢了。但再次,非常感谢指出我的问题。我应该阅读更多文档。
  • 但请查看CodeReview.SE 进行一般代码审查
猜你喜欢
  • 2014-04-01
  • 1970-01-01
  • 2013-08-14
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 2011-03-15
相关资源
最近更新 更多