2

I am trying to create a simulation of a simple robot which moves about in a 2-D world using pygame. There are obstacles in the world. The robot only has contact sensors. So it can only sense something if it collides either with the boundaries of the world or the obstacles in it. So, collision detection is of utmost importance here.

I have two principal classes World and Robot. The World class contains information about the geometry of the world and also contains a list of Obstacles. The Robot class contains information about the Geometry of the robot and it's current position in the world. I believe, (but I am not sure ) that Robot should be contained in the World class since it is a part of the world. The Robot has methods to display itself and move which changes its position in the world. But for collision detection, I need information about the World such as its boundaries and the list of obstacles.

Now, I could make work my simple simulation by making the World class instance a member of the Robot class. This way, my robot gets information about the world and I happily do the collision detection. But, this doesn't make me happy.

Because, I might want to extend the simulation by having other robots in the world and things in the world which I don't want to expose to the robot (I am just experimenting with various AI algorithms here). In future, I might want to try out something wherein the robot has 0 knowledge of the world and it gains knowledge by exploring it.

If this were Java, I would have created an interface (say RobotWorldKnowledge) which the World class would implement and pass this to the Robot class. This interface would have selective knowledge of the world which the robot would use.

I don't know how to do this in python. I tried Googling "interfaces in python" but couldn't find a proper example. Most answers tell that interfaces are not necessary in python.

I might be wrong in what I assumed. Please help me out.

Thanks in advance

shahensha

4

2 回答 2

1

Python 没有接口。也许您可以使用该abc模块编写一个抽象基类,并让您世界中的所有对象都实现抽象方法。

例如,您可以:

import abc

class RobotWorldKnowledge(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get_information(self, *args):
        pass

    ...


class Robot(RobotWorldKnowledge):
    def get_information(self, *args):
       ...

class World(RobotWorldKnowledge):
    def get_information(self, *args):
        ...

或者,您只需声明,当您在文档中提到一个RobotWorldKnowledge项目时,您的意思是一个对象实现了一个X具有特定签名的方法,该方法应该以某种方式返回信息......所以您在文档中定义接口并将其余所有内容留给回避-打字。

这是一个常见的解决方案(参见标准库中经常使用的类似文件的对象)。

于 2013-03-21T06:57:40.973 回答
-1

Python中有很好的接口框架——但它也可以创建一个快速而肮脏的东西——比如一个对象代理,它只会暴露底层对象的所需方法和属性。

这可以简单地__getattribute__在类中编写适当的方法来完成:

class Interface(object):
    def __init__(self, real_object, interface):
        if isinstance(interface, str):
            interface = interface.split()
        self.interface  = interface
        self.object = real_object
        Interface.validate(self)

    def __getattribute__(self, attr):
        # Retrieve the real attributes of self,
        # bypassing the normal attribute mechanism:
        interface = object.__getattribute__(self, "interface")
        real_object =  object.__getattribute__(self, "object")
        if attr in interface:
            return getattr(real_object, attr)
        raise AttributeError

    def validate(self):
        interface = object.__getattribute__(self, "interface")
        real_object =  object.__getattribute__(self, "object")
        for attr in interface:
            try:
                getattr(real_object, attr)
            except AttributeError:
                raise ValueError("Passed object does not conform to given interface")

和:

>>> class A(object):
...   a = 1 
...   b = 2
...   c = 3
... 
>>> a = A()
>>> b = Interface(a, "a b")
>>> b = Interface(a, "a b")>>> b.a
1
>>> b.b
2
>>> b.c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 16, in __getattribute__
AttributeError
>> class C(object): pass
... 
>>> Interface(C(), "a")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in __init__
  File "<stdin>", line 25, in validate
ValueError: Passed object does not conform to given interface
于 2013-03-21T02:52:24.757 回答