用Java思维方式编写Python代码

时间:2014-08-06 17:26:29

标签: python

我很确定我严重滥用Python,我需要协助修复它:

我过去一年在学校项目中使用过Java,并且在过去的几个月中只是略微使用了python。

我正处于python项目的中间,我真的觉得我在滥用语言和写作就好像我在使用Java一样。

例如: 我使用的是一个为我分析一些数据的特定引擎。因为它以特定的格式返回结果,所以我写了一个包装器对象来处理结果数据(在这种情况下,它接收一个json并从中获取相关的部分)。

由于我希望将来有一个抽象的Result类型,我创建了以下类,它实际上等同于Java抽象类:

class STTResult:

def get_text(self):
    raise NotImplementedError("This is an abstract class")

def get_confidence(self):
    raise NotImplementedError("This is an abstract class")

def get_intent(self):
    raise NotImplementedError("This is an abstract class")

def get_entities(self):
    raise NotImplementedError("This is an abstract class")

然后是具体的课程:

class WitResult(STTResult):

def __init__(self,json_result):
    self.text = json_result["_text"]
    self.confidence = json_result["outcomes"][0]["confidence"]
    self.intent = json_result["outcomes"][0]["intent"]
    self.entities = json_result["outcomes"][0]["entities"]


def get_text(self):
    return self.text

def get_confidence(self):
    return self.confidence

def get_intent(self):
    return self.intent

def get_entities(self):
    return self.entities

我非常确定这不是pythonic。 那么我怎样才能摆脱Java,C ++,C#思维模式和python心态?

澄清:并不是说我不知道​​python的语言/语法。我了解大多数基本功能和模块。

2 个答案:

答案 0 :(得分:1)

Python使用属性或属性而不是getter和setter。您可以直接访问变量。

class Point(object):
    def __init__(self):
        super().__init__()

        self.x = 0
        self.y = 0
        self.__my_private_variable = 0 # ".__" for private (Not really private)
    # end Constructor

    def update(self)
        """Do something to update the position on a graph."""
        pass
# end class Point

if __name__ == "__main__":
    p = Point()
    p.x = 1
    p.y = 1
    p.update()

getter和setter之类的另一种方法是使用属性

class Point(object):
    def __init__(self):
        super().__init__()

        self.__x = 0
        self.__y = 0
    # end Constructor

    @property
    def x(self):
        """The x value of a point."""
        return self.__x
    @x.setter
    def x(self, value):
        # Do setter stuff here
        self.__x = value
        self.update()
    # end x

    @property
    def y(self):
        """The y value of a point."""
        return self.__y
    @y.setter
    def y(self, value):
        self.set_y(value)
    # end y property

    def set_y(self, value):
        self.__y = value
        self.update()
    # end set_y

    def update(self):
        # Do something to update the position on a graph.
        pass
    # end update
# end class Point

if __name__ == "__main__":
    p = Point()
    p.x = 1
    p.y = 1
    # "p.x" uses @property method
    # "p.x = 0" uses @x.setter if you don't make an @x.setter then it is read only.
    # "del p.x" uses @x.deleter

之前保留了相同的语法样式,因此将属性更改为属性不会伤害任何内容。它还允许您执行获取,设置和删除操作。

另请参阅使用属性的其他语法(不带描述符)。我没有使用这种方法,所以我不完全确定语法。

class Point(object):
    def __init__(self):
        self.__x = 0
        self.x = property(fget=lambda: self.__x, fset=None, fdel=None, doc=None)

答案 1 :(得分:0)

如果您的结果“类”除了包含数据之外什么都不做,那么它也可能是dict。除非它确实像Justin Engel所建议的那样,有一个'更新'函数 - 但如果它遵循整个“这个对象有两个方法,一个是__init__()”的东西,那么可能没有不需要成为一个班级。 将容器作为对象并不一定是pythonic,因为Python允许面向对象的编程;如果您只是获取和设置数据,dict可能没问题。

>>> def make_result(json_data):
>>>     outs = json_data['outcomes'][0]
>>>     return dict(text=json_data['_text'], 
>>>                 confidence=outs['confidence'], 
>>>                 intent=outs['intent'], 
>>>                 entities=outs['entities']
>>>             )
>>> 
>>> MyResult = make_result(your_json_data)
>>> MyResult
{'confidence': 'extremely high', 'entities': ['Rose', 'Martha', 'Donna'], 'intent': 'fun', 'text': 'Allons-y!'}

如果确实需要成为新对象,请记住只有在对象具有属性时才需要getter和setter。例如,假设一个对象有三个属性:a,b和c - 而c总是a和b的总和。

>>> class Thing(object):
>>>     def __init__(self, a, b):
>>>         self.a = a
>>>         self.b = b
>>> 
>>>     @property
>>>     def c(self):
>>>         return self.a + self.b
>>> 
>>> Stick = Thing(4, 5)
>>> Stick.a
4
>>> Stick.b
5
>>> Stick.c
9

此属性没有setter,因此Stick.c = 34会导致错误:

Stick.c = 45
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>>

然而,这可能不是一个问题,如果您不熟悉在Python中创建属性,您可能需要阅读官方文档。

已经有不止一些博客写出......强烈的动机......指出Python不像Java那样有效。我的首要任务是http://bitworking.org/news/Python_isnt_Java_without_the_compile - 看看这个并得到一些例子,说明与Python的工作方式有多么不同。