python - 私有方法与计算的实例变量
问题描述
我已经有这个问题很长时间了,并且我已经看到两种方式都在实施。我想看看我什么时候会选择其中一个。
class Dog(object):
def __init__(self, color, breed, data=None):
self.color = color
self.breed = breed
self.data = data or {}
def print_owners(self):
owners = self._owners()
for owner in owners:
print(owner)
def _owners(self):
return self.data.get('previous_owners', [])
或者,
class Dog(object):
def __init__(self, color, breed, data=None):
self.color = color
self.breed = breed
self.data = data or {}
self._owners = self.data.get('previous_owners', [])
def print_owners(self):
for owner in self._owners:
print(owner)
data = {
'dob': '05/05/2019',
'previous_owners': ['Miguel Francisco','Juan Paulo', 'Ofelia']
}
pepito = Dog('black', 'chihuahua', data)
pepito.print_owners()
两种方式都有效,但我想看看我会选择其中一种的用例和原因。
我在 Ruby on Rails 上做了 2 年,我看到第一种方式被更频繁地实现。然后,我搬到了另一家使用 Python 的公司,并且更经常地实施第二种方式。我不喜欢该__init__
方法被过度填充,但同时,我不喜欢方法的过度创建会产生某种类似反模式的行为。
解决方案
如果您将代码的最后一位更改为:
data = {
'dob': '05/05/2019',
'previous_owners': ['Miguel Francisco','Juan Paulo', 'Ofelia']
}
pepito = Dog('black', 'chihuahua', data)
data['previous_owners'] = ['who', 'are', 'these', 'people']
pepito.print_owners()
在第一个实现中,单词、'who'
和被打印出来。'are'
'these'
'people'
在第二个实现中,名称'Miguel Francisco'
和'Juan Paulo'
被'Ofelia'
打印出来。
不同之处在于第二个实现在初始化时设置属性self._owners
,这意味着data['previous_owners']
指向的列表与该实例相关联,即使您稍后删除或修改data['previous_owners']
指向的内容。另一方面,第一个实现必须检索 每次调用该方法data['previous_owners']
时指向_owners
的值,这意味着调用print_owners
可能会导致不同的结果,具体取决于您是否修改了与 关联的值data['previous_owners']
。
哪种实现是“最好的”取决于您的特定用例:您是希望在初始化时设置该属性(第二个实现),还是随着代码的进行动态修改它(第一个实现)?
另请注意,在第一个实现中,_owners
是一个伪装成方法的属性,因此对于 Pythonic 代码,您真正想要的是@property
那里的装饰器:
class Dog(object):
def __init__(self, color, breed, data=None):
self.color = color
self.breed = breed
self.data = data or {}
def print_owners(self):
for owner in self._owners:
print(owner)
@property
def _owners(self):
return self.data.get('previous_owners', [])
推荐阅读
- javascript - 如何在javascript中划分多个数组
- ansible - ansible playbook 用于检查目标主机的服务器可达性
- reactjs - React - 将道具传递给特定的孩子
- julia - 在 Julia 中的同一图形上绘制多个 ODE 解决方案的最佳方法是什么?
- javascript - 如何将上传的图片插入位于另一张图片上的框架中?
- clang - 为 WebAssembly 创建程序集数据部分
- php - imagick 只保存 gif 的第一帧
- java - Android Studio Firestore RecyclerView
- codeigniter - 如何在 Codeigniter 4 的同一行中编写方法和分页
- python - 匹配两个 seaborn 地块的图例颜色