Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python |(接口?)中一个类的方法和变量对另一个类的选择性公开_Python_Oop_Interface - Fatal编程技术网

Python |(接口?)中一个类的方法和变量对另一个类的选择性公开

Python |(接口?)中一个类的方法和变量对另一个类的选择性公开,python,oop,interface,Python,Oop,Interface,我正试图用pygame创建一个简单机器人的模拟,它在二维世界中移动。世界上有障碍。机器人只有接触传感器。因此,只有当它与世界的边界或其中的障碍物发生碰撞时,它才能感觉到某些东西。因此,碰撞检测在这里至关重要 我有两个主要的课程:世界和机器人。世界类包含有关世界几何体的信息,还包含障碍物列表。Robot类包含有关机器人几何体及其在世界上的当前位置的信息。我相信(但我不确定)机器人应该被纳入世界级,因为它是世界的一部分。机器人有显示自己和移动的方法,从而改变了它在世界上的位置。但是对于碰撞检测,我需

我正试图用pygame创建一个简单机器人的模拟,它在二维世界中移动。世界上有障碍。机器人只有接触传感器。因此,只有当它与世界的边界或其中的障碍物发生碰撞时,它才能感觉到某些东西。因此,碰撞检测在这里至关重要

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

现在,我可以通过使世界级实例成为Robot类的成员来完成我的简单模拟工作。通过这种方式,我的机器人获得了关于世界的信息,我很高兴地进行了碰撞检测。但是,这并不能让我快乐

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

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

我不知道如何在python中实现这一点。我尝试用谷歌搜索“python中的接口”,但找不到合适的示例。大多数答案告诉我们,接口在python中是不必要的

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

提前谢谢


shahensha

Python中有很好的接口框架- 但创造一个又快又脏的东西也是一回事- 类似于只公开底层对象所需的方法和属性的对象代理

只需在类中编写适当的
\uuuu getattribute\uuu
方法即可完成此操作:

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")
以及:

>>A类(对象):
...   a=1
...   b=2
...   c=3
... 
>>>a=a()
>>>b=接口(a,“a b”)
>>>b=接口(a,“AB”)>>>b.a
1.
>>>b.b
2.
>>>不列颠哥伦比亚省
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第16行,在__
属性错误
>>C类(对象):通过
... 
>>>接口(C(),“a”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第7行,在_init中__
验证中第25行的文件“”
ValueError:传递的对象不符合给定接口

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

例如,您可以:

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类型


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

Java接口是静态类型系统的一部分。它告诉编译器类实现了某些方法。Python没有静态类型系统,因此没有Java接口的Python等价物。询问代码的问题必须证明对所解决问题的最低理解。包括尝试过的解决方案、它们不起作用的原因以及预期结果。另请参见:堆栈溢出问题检查表
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):
        ...