从对象获取属性的 Pythonic 方式是什么?
What is the Pythonic way of getting attributes from objects?
我有一个代表 Atom 的 class,它有两组坐标,其中一组是笛卡尔坐标,我想遵循最佳架构实践从 class.
以前我创建了多个 class 方法来获取不同类型的属性,但我觉得这不是 pythonic,并且不必要地使我的代码混乱,但是我不确定通常的解决方案是什么.
因为它可能会帮助别人回答,请参阅下面的 Atom class:
class Atom():
def __init__(self, element, x_coord, y_coord, z_coord):
'''
Instantiate new atom object.
'''
#Check information is correct
if not isinstance(element, str):
raise ValueError('Element must be a string.')
if not isinstance(x_coord, int) and not isinstance(x_coord, float):
raise ValueError('All coordinates must be numeric, x is not.')
if not isinstance(y_coord, int) and not isinstance(y_coord, float):
raise ValueError('All coordinates must be numeric, y is not.')
if not isinstance(z_coord, int) and not isinstance(z_coord, float):
raise ValueError('All coordinates must be numeric, z is not.')
self.coordinates = np.array([x_coord, y_coord, z_coord]).astype(float)
self.cartesian = None
self.element = element
def __repr__(self):
'''
Atom representation.
'''
x, y, z = list(self.coordinates)
return f"Atom('{self.element}', {x}, {y}, {z})"
def __copy__(self):
x, y, z = [float(x) for x in list(self.coordinates)]
return Atom(self.element, x, y, z)
def set_cartesian(self, vector_space):
'''
Set the cartesian coordinates of the atom, based on a vector space -
generally that of a unitcell. Requires column vectors.
'''
self.cartesian = vector_space @ self.coordinates.T
我最好使用一个方法来处理所有属性,以保持 class 整洁。我知道我可以只使用“class.attribute”,但据我所知,如果你想重命名某些东西,这可能会导致代码长期中断。
有几种方法可以解决这个问题。需要记住的几件事:
- Python 没有大量输入——事实上,它几乎没有输入
- 在编写 python 代码时从 C++ 的角度思考通常很有用
现在,在我看来,您似乎想要一个方法来包含 Atom 的大部分(如果不是全部)属性。如果我要在 C++ 中解决这个问题,我很可能会创建一个 struct 数据类型来使用和使用类似 Atom.GetAttributtes() 到该结构的 return 变量的东西类型。
但是,这是 Python,所以我们可以利用第 1 点:Python 的输入不多。
因此,您可以简单地将 Atom.GetAttrbutes() return 包含所有属性的列表、元组或数组(您甚至可以将包含笛卡尔坐标的数组嵌套在列表中其他属性)
但是,当您说让多个方法获取不同的属性数据“不是 pythonic”时,我不确定您的意思。我会将您的注意力转移到第 2 点:在编写 python 代码时从 C++ 的角度思考通常很有用。
在 C++ 中,拥有多个方法(称为 成员函数 )绝对是处理 return 属性(称为 成员变量 ), 所以这也是在 python 中做事的完美方式。这是因为拥有几个不同的函数 return 不同的属性将使您的程序 运行 更快 。为什么?因为如果您采用上述方法(return将您的属性作为列表、元组或数组)并使用 仅 方式来访问您的属性,您将 运行 遇到这样的情况,比方说,您只想要一个原子的元素,但现在您必须获取所有数据(速度较慢,因为 python 必须找到所有数据并将它们放入列表中)和他们从数据中取出元素(速度较慢,原因很明显。)现在,这并不意味着你不应该有一种方法来一次 return 所有属性(在某些情况下这是有用的也是),但是您也应该有方法来单独访问您的属性。这只是很好的编程,不特定于 C++ 或任何其他语言。
我有一个代表 Atom 的 class,它有两组坐标,其中一组是笛卡尔坐标,我想遵循最佳架构实践从 class.
以前我创建了多个 class 方法来获取不同类型的属性,但我觉得这不是 pythonic,并且不必要地使我的代码混乱,但是我不确定通常的解决方案是什么.
因为它可能会帮助别人回答,请参阅下面的 Atom class:
class Atom():
def __init__(self, element, x_coord, y_coord, z_coord):
'''
Instantiate new atom object.
'''
#Check information is correct
if not isinstance(element, str):
raise ValueError('Element must be a string.')
if not isinstance(x_coord, int) and not isinstance(x_coord, float):
raise ValueError('All coordinates must be numeric, x is not.')
if not isinstance(y_coord, int) and not isinstance(y_coord, float):
raise ValueError('All coordinates must be numeric, y is not.')
if not isinstance(z_coord, int) and not isinstance(z_coord, float):
raise ValueError('All coordinates must be numeric, z is not.')
self.coordinates = np.array([x_coord, y_coord, z_coord]).astype(float)
self.cartesian = None
self.element = element
def __repr__(self):
'''
Atom representation.
'''
x, y, z = list(self.coordinates)
return f"Atom('{self.element}', {x}, {y}, {z})"
def __copy__(self):
x, y, z = [float(x) for x in list(self.coordinates)]
return Atom(self.element, x, y, z)
def set_cartesian(self, vector_space):
'''
Set the cartesian coordinates of the atom, based on a vector space -
generally that of a unitcell. Requires column vectors.
'''
self.cartesian = vector_space @ self.coordinates.T
我最好使用一个方法来处理所有属性,以保持 class 整洁。我知道我可以只使用“class.attribute”,但据我所知,如果你想重命名某些东西,这可能会导致代码长期中断。
有几种方法可以解决这个问题。需要记住的几件事:
- Python 没有大量输入——事实上,它几乎没有输入
- 在编写 python 代码时从 C++ 的角度思考通常很有用
现在,在我看来,您似乎想要一个方法来包含 Atom 的大部分(如果不是全部)属性。如果我要在 C++ 中解决这个问题,我很可能会创建一个 struct 数据类型来使用和使用类似 Atom.GetAttributtes() 到该结构的 return 变量的东西类型。
但是,这是 Python,所以我们可以利用第 1 点:Python 的输入不多。
因此,您可以简单地将 Atom.GetAttrbutes() return 包含所有属性的列表、元组或数组(您甚至可以将包含笛卡尔坐标的数组嵌套在列表中其他属性)
但是,当您说让多个方法获取不同的属性数据“不是 pythonic”时,我不确定您的意思。我会将您的注意力转移到第 2 点:在编写 python 代码时从 C++ 的角度思考通常很有用。
在 C++ 中,拥有多个方法(称为 成员函数 )绝对是处理 return 属性(称为 成员变量 ), 所以这也是在 python 中做事的完美方式。这是因为拥有几个不同的函数 return 不同的属性将使您的程序 运行 更快 。为什么?因为如果您采用上述方法(return将您的属性作为列表、元组或数组)并使用 仅 方式来访问您的属性,您将 运行 遇到这样的情况,比方说,您只想要一个原子的元素,但现在您必须获取所有数据(速度较慢,因为 python 必须找到所有数据并将它们放入列表中)和他们从数据中取出元素(速度较慢,原因很明显。)现在,这并不意味着你不应该有一种方法来一次 return 所有属性(在某些情况下这是有用的也是),但是您也应该有方法来单独访问您的属性。这只是很好的编程,不特定于 C++ 或任何其他语言。