dm0*_*514 21 python oop instance-variables
我正在创建一个查询构建器类,它将帮助从URL params构建mongodb的查询.除了使用基本的语言结构和使用django的内置模型之外,我从未做过太多面向对象的编程,或者设计了除我自己以外的人使用的类.
所以我有这QueryBuilder门课
class QueryHelper():
"""
Help abstract out the problem of querying over vastly
different dataschemas.
"""
def __init__(self, collection_name, field_name, params_dict):
self.query_dict = {}
self.params_dict = params_dict
db = connection.get_db()
self.collection = db[collection_name]
def _build_query(self):
# check params dict and build a mongo query
pass
Run Code Online (Sandbox Code Playgroud)
现在,_build_query我将检查params_dict和填充,query_dict以便将其传递给mongo的find()功能.在这样做时,我只是想知道是否有一个绝对正确的方法,因为是否_build_query应该返回字典或是否应该只修改self.query_dict.因为它是一个内部方法,我认为只需修改即可self.query_dict.是否有正确的方法(pythonic)接近这个?这只是愚蠢而不是重要的设计决定吗?任何帮助表示赞赏.
Sim*_*ser 11
修改self.query_dict是完全正确的,因为面向对象编程的整个想法是方法可以修改对象的状态.只要方法在方法完成后处于一致状态,你就可以了.这事实上_build_query是一个内部方法无所谓.您可以选择_build_query在__init__创建对象之后调用in 来构造查询.
该决定主要用于测试目的.为了进行毛皮测试,可以方便地单独测试每个方法,而无需测试整个对象的状态.但是这不适用于这种情况,因为我们讨论的是内部方法,所以你自己决定何时调用该方法,而不是其他对象或其他代码.
如果你有任何回报,我建议self.self从实例方法返回对于方法链接很方便,因为每个返回值允许对同一对象进行另一个方法调用:
foo.add_thing(x).add_thing(y).set_goal(42).execute()
Run Code Online (Sandbox Code Playgroud)
这有时被称为"流畅的"API.
然而,虽然Python允许方法链接到不可变类型,例如int和str,它不提供可变容器的方法,例如list和set-by设计 - 所以可以说它不是"Pythonic"来为你自己的可变类型做.尽管如此,许多Python库确实拥有"流畅"的API.
缺点是这样的API会使调试变得更难.由于您执行整个语句或不执行任何语句,因此您无法在语句中的中间点轻松查看对象.当然,我通常发现print完全适合调试Python代码,所以我只是抛出一个print我感兴趣的返回值的方法!
返回一个值是可取的,因为它允许您将所有属性修改保存在一个地方(__init__).此外,这使得以后更容易扩展代码; 假设您要_build_query在子类中重写,那么重写方法只能返回一个值,而无需知道要设置哪个属性.这是一个例子:
class QueryHelper(object):
def __init__(self, param, text):
self._param = param
self._query = self._build_query(text)
def _build_query(self, text):
return text + " and ham!"
class RefinedQueryHelper(QueryHelper):
def _build_query(self, text):
# no need to know how the query object is going to be used
q = super(RefinedQueryHelper, self)._build_query()
return q.replace("ham", "spam")
Run Code Online (Sandbox Code Playgroud)
与"制定者版本":
class QueryHelper(object):
def __init__(self, param, text):
self._param = param
self._build_query(text)
def _build_query(self, text):
self._query = text + " and ham!"
class RefinedQueryHelper(QueryHelper):
def _build_query(self, text):
# what if we want to store the query in __query instead?
# then we need to modify two classes...
super(RefinedQueryHelper, self)._build_query()
self._query = self._query.replace("ham", "spam")
Run Code Online (Sandbox Code Playgroud)
如果您确实选择设置属性,则可能需要调用该方法_set_query以保持清晰.
虽然对象的方法直接修改其状态是很常见的,但有时将对象作为其自己的“客户端”并通过(通常)私有访问方法间接访问自己是有利的。在 Python 中,您可以通过使用内置property()类/函数轻松完成此操作。
这样做提供了更好的封装和随之而来的好处(与实现细节隔离是主要的)。然而,这样做可能不切实际,因为它需要太多额外的代码并且通常速度较慢,这可能会对性能产生不可接受的负面影响——因此通常必须针对这种理想情况进行权衡。
| 归档时间: |
|
| 查看次数: |
2548 次 |
| 最近记录: |