简体   繁体   English

Python 正在调用基数 class 而不是派生的 class

[英]Python is calling the base class instead of the derived class

I am new to python. I am trying to implement the most basic version of a reflex agent in Python. A lot of the code, in fact, pretty much all of it has been copied from the repo that it came from.我是 python 的新手。我正在尝试在 Python 中实现反射代理的最基本版本。实际上,很多代码几乎都是从它来自的 repo 中复制的。 I am trying to trim it down to understand it better but there seems to be a problem with the code.我试图精简它以更好地理解它,但代码似乎有问题。

import collections
import collections.abc
import numbers
import random


class Thing:
    def __repr__(self):
        return '<{}>'.format(getattr(self, '__name__', self.__class__.__name__))

    def is_alive(self):
        return hasattr(self, 'alive') and self.alive

    def show_state(self):
        print("I don't know how to show_state.")


class Agent(Thing):
    def __init__(self, program=None):
        self.alive = True
        self.bump = False
        self.holding = []
        self.performance = 0
        if program is None or not isinstance(program, collections.abc.Callable):
            print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__))

            def program(percept):
                return eval(input('Percept={}; action? '.format(percept)))

        self.program = program

    def can_grab(self, thing):
        """Return True if this agent can grab this thing.
        Override for appropriate subclasses of Agent and Thing."""
        return False

loc_A, loc_B = (0, 0), (1, 0)

def ReflexVacuumAgent():
    def program(percept):
        print("calling correct")
        ## ---------------------------
        ## here is the issue
        ## ---------------------------
        location, status = percept
        if status == 'Dirty':
            return 'Suck'
        elif location == loc_A:
            return 'Right'
        elif location == loc_B:
            return 'Left'

    return Agent(program)


class Environment:
    def __init__(self):
        self.things = []
        self.agents = []

    def thing_classes(self  ):
        return []  # List of classes that can go into environment

    def percept(self, agent):
        """Return the percept that the agent sees at this point. (Implement this.)"""
        raise NotImplementedError

    def default_location(self, thing):
        """Default location to place a new thing with unspecified location."""
        return None

    def is_done(self):
        """By default, we're done when we can't find a live agent."""
        return not any(agent.is_alive() for agent in self.agents)

    def step(self):
        """Run the environment for one time step. If the
        actions and exogenous changes are independent, this method will
        do. If there are interactions between them, you'll need to
        override this method."""
        if not self.is_done():
            actions = []
            for agent in self.agents:
                if agent.alive:
                    actions.append(agent.program(self.percept(agent)))
                else:
                    actions.append("")
            for (agent, action) in zip(self.agents, actions):
                self.execute_action(agent, action)
            self.exogenous_change()

    def add_thing(self, thing, location=None):
        """Add a thing to the environment, setting its location. For
        convenience, if thing is an agent program we make a new agent
        for it. (Shouldn't need to override this.)"""
        if not isinstance(thing, Thing):
            thing = Agent(thing)
        if thing in self.things:
            print("Can't add the same thing twice")
        else:
            thing.location = location if location is not None else self.default_location(thing)
            self.things.append(thing)
            if isinstance(thing, Agent):
                thing.performance = 0
                self.agents.append(thing)


class Dirt(Thing):
    pass


class TrivialVacuumEnvironment(Environment):
    def __init__(self):
        super().__init__()
        self.status = {loc_A: random.choice(['Clean', 'Dirty']),
                       loc_B: random.choice(['Clean', 'Dirty'])}

    def percept(self, agent):
        return self.status[agent.location]

    def thing_classes(self):
        return [Dirt, ReflexVacuumAgent]




# instantiate trivial environment 
env = TrivialVacuumEnvironment()
# instantiate trivial agent
agnt = ReflexVacuumAgent()
# add agent to environment
env.add_thing(agnt, location=loc_A)
# step forward
env.step() 

I have highlighted what I have found via debugging.我突出显示了我通过调试发现的内容。 Unfortunately I don't have the python skills to do anything about it.不幸的是,我没有 python 技能来做任何事情。

The error I am getting is as follows我得到的错误如下

Traceback (most recent call last):
  File "/home/anthonygoddard962/git/agents/environment.py", line 137, in <module>
    env.step() 
  File "/home/anthonygoddard962/git/agents/environment.py", line 88, in step
    actions.append(agent.program(self.percept(agent)))
  File "/home/anthonygoddard962/git/agents/environment.py", line 45, in program
    location, status = percept
ValueError: too many values to unpack (expected 2)



After fixing some school boy errors with python I have some working code.在用 python 修复了一些男生错误后,我有了一些工作代码。 The compiling code is below.编译代码如下。

import collections
import collections.abc
import numbers
import random


class Thing:
    def __repr__(self):
        return '<{}>'.format(getattr(self, '__name__', self.__class__.__name__))

    def is_alive(self):
        return hasattr(self, 'alive') and self.alive

    def show_state(self):
        print("I don't know how to show_state.")


class Agent(Thing):
    def __init__(self, program=None):
        self.alive = True
        self.bump = False
        self.holding = []
        self.performance = 0
        if program is None or not isinstance(program, collections.abc.Callable):
            print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__))

            def program(percept):
                return eval(input('Percept={}; action? '.format(percept)))

        self.program = program

    def can_grab(self, thing):
        """Return True if this agent can grab this thing.
        Override for appropriate subclasses of Agent and Thing."""
        return False

loc_A, loc_B = (0, 0), (1, 0)

def ReflexVacuumAgent():
    def program(percept):
        location, status = percept
        if status == 'Dirty':
            return 'Suck'
        elif location == loc_A:
            return 'Right'
        elif location == loc_B:
            return 'Left'
    
    return Agent(program)


class Environment:
    def __init__(self):
        self.things = []
        self.agents = []

    def thing_classes(self  ):
        return []  # List of classes that can go into environment

    def percept(self, agent):
        """Return the percept that the agent sees at this point. (Implement this.)"""
        raise NotImplementedError

    def execute_action(self, agent, action):
        """Change the world to reflect this action. (Implement this.)"""
        raise NotImplementedError

    def default_location(self, thing):
        """Default location to place a new thing with unspecified location."""
        return None

    def is_done(self):
        """By default, we're done when we can't find a live agent."""
        return not any(agent.is_alive() for agent in self.agents)

    def step(self):
        if not self.is_done():
            actions = []
            for agent in self.agents:
                if agent.alive:
                    actions.append(agent.program(self.percept(agent)))
                else:
                    actions.append("")
            for (agent, action) in zip(self.agents, actions):
                self.execute_action(agent, action)

    def add_thing(self, thing, location=None):
        if not isinstance(thing, Thing):
            thing = Agent(thing)
        if thing in self.things:
            print("Can't add the same thing twice")
        else:
            thing.location = location if location is not None else self.default_location(thing)
            self.things.append(thing)
            if isinstance(thing, Agent):
                thing.performance = 0
                self.agents.append(thing)


class Dirt(Thing):
    pass


class TrivialVacuumEnvironment(Environment):
    def __init__(self):
        super().__init__()
        self.status = {loc_A: random.choice(['Clean', 'Dirty']),
                       loc_B: random.choice(['Clean', 'Dirty'])}

    def percept(self, agent):
        return agent.location, self.status[agent.location]

    def execute_action(self, agent, action):
        if(action == 'Right'):
            agent.location = (1, 0)
        if(action == 'Left'):
            agent.location = (0, 0)
        if(action == 'Suck'):
            self.status[agent.location] = 'Clean'

    def show_status(self):
        print(self.status)

    def thing_classes(self):
        return [Dirt, ReflexVacuumAgent]




# instantiate trivial environment 
env = TrivialVacuumEnvironment()
# instantiate trivial agent
agnt = ReflexVacuumAgent()
# add agent to environment
env.add_thing(agnt, location=loc_A)
env.show_status()
print(agnt.location)
# step forward and show status
env.step() 
env.show_status()
print(agnt.location)
# ...and again
env.step() 
env.show_status()
print(agnt.location)
# ...and again
env.step() 
env.show_status()
print(agnt.location)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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