首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中选择性地将一个类的方法和变量公开给另一个类|(interface?)

在Python中选择性地将一个类的方法和变量公开给另一个类|(interface?)
EN

Stack Overflow用户
提问于 2013-03-21 10:40:14
回答 2查看 149关注 0票数 2

我正在尝试创建一个简单的机器人的模拟,它在2-D世界中移动使用pygame。世界上有很多障碍。机器人只有接触感应器。因此,只有当它与世界的边界或其中的障碍发生碰撞时,它才能感觉到某些东西。因此,碰撞检测在这里非常重要。

我有两个主要的类World和Robot。World类包含有关世界几何体的信息,还包含障碍物列表。Robot类包含有关机器人的几何体及其在世界中的当前位置的信息。我相信(但我不确定),机器人应该包含在世界级,因为它是世界的一部分。机器人有显示自己和移动的方法,这改变了它在世界上的位置。但是对于碰撞检测,我需要关于World的信息,比如它的边界和障碍物列表。

现在,我可以通过使World类实例成为Robot类的成员来使work成为我的简单模拟。这样,我的机器人就可以获得关于世界的信息,而我也可以很高兴地进行碰撞检测。但是,这并不能让我开心。

因为,我可能想通过让世界上的其他机器人和世界上我不想暴露给机器人的东西来扩展模拟(我只是在这里试验各种AI算法)。将来,我可能想尝试一些机器人对世界一无所知,并通过探索获得知识的东西。

如果这是Java,我会创建一个接口(比方说RobotWorldKnowledge),World类将实现该接口并将其传递给Robot类。这个接口将有选择性地了解机器人将使用的世界。

我不知道如何在python中做到这一点。我试着在谷歌上搜索“在python中的接口”,但是找不到合适的例子。大多数答案告诉我们,接口在python中不是必需的。

我的假设可能是错的。请帮帮我。

提前感谢

沙河沙

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-21 10:52:25

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

这可以通过在类中编写一个适当的__getattribute__方法来完成:

代码语言:javascript
复制
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")

和:

代码语言:javascript
复制
>>> 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
票数 -1
EN

Stack Overflow用户

发布于 2013-03-21 14:57:41

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

例如,您可以拥有:

代码语言:javascript
复制
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方法的对象,该方法应以某种方式返回信息……因此,您可以在文档中定义接口,而将其余的工作留给duck- the来完成。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15538506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档