刚开始向天域对象添加属性“可以”吗?

2024-05-16 00:12:40 发布

您现在位置:Python中文网/ 问答频道 /正文

在这里,“OK”当然是指AYOR(风险自负),但是如果避免与现有属性名称发生明显冲突,则不会出现可预见的问题。你知道吗

Skyfield物体——尤其是行星——通常具有数量有限的属性。我经常编写简短的脚本来提取我保存为文本并稍后使用的数字数据。这些基本上是“一次性”脚本,因为我很少使用它们一次或两次以上,而且从不共享它们。你知道吗

当我编写更持久的代码时,我当然会创建自己的容器对象。你知道吗

我的问题:它似乎对我很有效,所以在这个特定上下文中,除了属性名冲突之外,还有什么可能出错的吗?你知道吗

from skyfield.api import load
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

eph   = load('de421.bsp')
earth = eph['earth']
sun   = eph['sun']

ts = load.timescale()

t  = ts.utc(2016, 1, np.linspace(0, 366, 1000))

# SLOPPY WAY: just add them directly
earth.pos  = earth.at(t).position.km
sun.pos    = sun.at(t).position.km
earth.r    = np.sqrt(((earth.pos-sun.pos)**2).sum(axis=0))
earth.peri = earth.r.min()
earth.apo  = earth.r.max()

print earth.peri, earth.apo, earth.pos.shape


# BETTER WAY: tedious but more cautious
uhoh  = dict()
ep    = earth.at(t).position.km
sp    = sun.at(t).position.km
r     = np.sqrt(((ep-sp)**2).sum(axis=0))
uhoh['pos']  = ep
uhoh['r']    = r
uhoh['peri'] = r.min()
uhoh['apo']  = r.max()
earth.uhoh   = uhoh

print earth.uhoh['peri'], earth.uhoh['apo'], earth.uhoh['pos'].shape

退货:

147100175.99 152103762.948 (3, 1000)
147100175.99 152103762.948 (3, 1000)

Tags: posimport属性nppositionloadatep
1条回答
网友
1楼 · 发布于 2024-05-16 00:12:40

这确实是一种在非正式Python代码中偶尔会遇到的模式。除了将来的属性名冲突之外,另一个可能出错的主要问题是,库作者在希望更有效地创建数百万个对象的人的怂恿下,添加了__slots__规范,当您尝试添加其他属性时,就会出现错误。你知道吗

__slots__的防御,如果出现的话,就是使用你自己想要使用的类的子类。如果子类也不能指定__slots__——至少说__slots__ = [],即使它没有想要添加的属性——那么子类的实例是完全开放的,可以有任何属性,因此您可以创建自己的子类来“解锁”实例并让它们有任何属性。你知道吗

请注意,像earth这样的对象有资格成为字典键,因此,如果您有一条要与每个行星关联的信息,可以这样说:

positions = {}
positions[earth] = ...

这是一种常见的模式,当您需要记住关于一组对象中的每个对象的额外信息时。你知道吗

相关问题 更多 >