我很确定我严重滥用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的语言/语法。我了解大多数基本功能和模块。答案 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的工作方式有多么不同。