python class 对成员的操作与静态方法
python class operations on members vs static methods
我需要一些帮助来为我的 python class.
找出正确的 OOP 设计选择
在我的示例中,字母是在不同的步骤中附加到字符串中的。然后打印该字符串。对于这个应用程序,获取中间结果对用户来说并不是很重要。
那么将字符串传递给构造函数然后使用私有方法进行操作并使用 dothings
方法调用它们会更好吗?
class A:
def __init__(self, string: str()):
self.string = string
def _append_a(self):
self.string += "a"
def _append_b(self):
self.string += "b"
def dothings(self):
_append_a()
_append_b()
def export(self):
print(self.string)
还是将字符串传递给每个方法更好?
class AA:
@staticmethod
def append_a(string):
string += "a"
return string
@staticmethod
def append_b(string):
string += "b"
return string
@staticmethod
def export(string):
print(string)
我觉得A
的界面比较干净,直接调用dothings
然后导出即可。
但是,class A
有点像黑盒子,而使用 class AA
用户可以更深入地了解正在发生的事情。
有'right'选择吗?
AA
很容易被驳回。它没有任何面向对象的东西:它只是三个常规函数,被收集到一个命名空间中。没有由一组方法操作的共享状态。没有建议只有一个函数的输出是另一个函数的有效输入。比如意图大概是写成
这样的
export(append_a(append_b("foo"))) # fooba
但没有什么需要遵循这种模式。无论如何,这些功能彼此无关。
A
与 builder pattern 有一些共同之处。给定一个初始字符串,您可以向其附加 a
s 和 b
s,但不能附加任何其他内容(不违反方法提供的封装。最终,您通过调用 [=17 获得“最终”值=],所以它代表的工作流程是这样的:
a = A("foo")
a.append_a()
a.append_a()
a.append_b()
a.append_b()
a.append_a()
a.export() # fooaabba
如图所示的 class 几乎非常简单,但演示了如何提供定义良好的接口以从初始种子构建字符串值。你不能随心所欲地做任何你喜欢的事情:你不能在前面添加值,你不能删除现有的字符,等等
为了更符合构建器模式,我将 A
修改如下:
class A:
def __init__(self, string: str):
self.string = string
def append_a(self):
self.string += "a"
def append_b(self):
self.string += "b"
def append_ab(self):
self.append_a()
self.append_b()
def export(self):
return self.string + "c"
只要您不直接访问 string
属性,此 class 会限制您可以构建的字符串类型:
- 您可以从任意词干开始(
__init__
的参数)
- 您可以将
a
附加到字符串
- 您可以将
b
附加到字符串
- 您可以将
ab
附加到字符串(但这只是调用 append_a
后跟 append_b
的便捷快捷方式,正如实现所暗示的那样)
- 您可以结束字符串
c
你通过调用 export
获得你的最终值(我修改它只是为了说明你不能在任何时候添加 c
,所以没有办法遵循 c
与另一个 a
,例如)。
在某种意义上,它有点像正则表达式的对偶:不是 识别 字符串是否与正则表达式 .*(a|b)*c
匹配,而是 创建一个将匹配正则表达式的字符串。
我需要一些帮助来为我的 python class.
找出正确的 OOP 设计选择在我的示例中,字母是在不同的步骤中附加到字符串中的。然后打印该字符串。对于这个应用程序,获取中间结果对用户来说并不是很重要。
那么将字符串传递给构造函数然后使用私有方法进行操作并使用 dothings
方法调用它们会更好吗?
class A:
def __init__(self, string: str()):
self.string = string
def _append_a(self):
self.string += "a"
def _append_b(self):
self.string += "b"
def dothings(self):
_append_a()
_append_b()
def export(self):
print(self.string)
还是将字符串传递给每个方法更好?
class AA:
@staticmethod
def append_a(string):
string += "a"
return string
@staticmethod
def append_b(string):
string += "b"
return string
@staticmethod
def export(string):
print(string)
我觉得A
的界面比较干净,直接调用dothings
然后导出即可。
但是,class A
有点像黑盒子,而使用 class AA
用户可以更深入地了解正在发生的事情。
有'right'选择吗?
AA
很容易被驳回。它没有任何面向对象的东西:它只是三个常规函数,被收集到一个命名空间中。没有由一组方法操作的共享状态。没有建议只有一个函数的输出是另一个函数的有效输入。比如意图大概是写成
export(append_a(append_b("foo"))) # fooba
但没有什么需要遵循这种模式。无论如何,这些功能彼此无关。
A
与 builder pattern 有一些共同之处。给定一个初始字符串,您可以向其附加 a
s 和 b
s,但不能附加任何其他内容(不违反方法提供的封装。最终,您通过调用 [=17 获得“最终”值=],所以它代表的工作流程是这样的:
a = A("foo")
a.append_a()
a.append_a()
a.append_b()
a.append_b()
a.append_a()
a.export() # fooaabba
如图所示的 class 几乎非常简单,但演示了如何提供定义良好的接口以从初始种子构建字符串值。你不能随心所欲地做任何你喜欢的事情:你不能在前面添加值,你不能删除现有的字符,等等
为了更符合构建器模式,我将 A
修改如下:
class A:
def __init__(self, string: str):
self.string = string
def append_a(self):
self.string += "a"
def append_b(self):
self.string += "b"
def append_ab(self):
self.append_a()
self.append_b()
def export(self):
return self.string + "c"
只要您不直接访问 string
属性,此 class 会限制您可以构建的字符串类型:
- 您可以从任意词干开始(
__init__
的参数) - 您可以将
a
附加到字符串 - 您可以将
b
附加到字符串 - 您可以将
ab
附加到字符串(但这只是调用append_a
后跟append_b
的便捷快捷方式,正如实现所暗示的那样) - 您可以结束字符串
c
你通过调用 export
获得你的最终值(我修改它只是为了说明你不能在任何时候添加 c
,所以没有办法遵循 c
与另一个 a
,例如)。
在某种意义上,它有点像正则表达式的对偶:不是 识别 字符串是否与正则表达式 .*(a|b)*c
匹配,而是 创建一个将匹配正则表达式的字符串。