在使用spyder IDE 编写新类并使用pylint检查最终结果时,我遇到了错误消息(但代码按预期工作而没有错误).
上下文:在构造函数中,我想创建新成员(非常多).通常,这些很少,所以我使用这个编码:
class MyClass():
def __init__(self):
self.a = ...
self.b = ...
Run Code Online (Sandbox Code Playgroud)
但是在很多成员的情况下(假设是10),所有设置为相同的初始值(假设它们都是dict()),我很想这样做:
class MyClass():
def __init__(self):
_vars = ["a", "b", "c", ...]
for _var in _vars:
self.__dict__[_var] = dict()
Run Code Online (Sandbox Code Playgroud)
在课堂上,我正在使用以下成员来引用成员:
class MyClass():
def my_method(self):
print self.c
Run Code Online (Sandbox Code Playgroud)
错误与pylint的(在Spyder的):
在此文件上使用pylint时,我收到一条错误消息:
MyClass.my_method:'MyClass'的实例没有'c'member.
但是,代码运行得很好,没有错误,即.我可以毫无问题地访问会员'c'.
问题:这是一个正确的编码,还是应该避免这种方法来初始化成员?
上下文: 我最近发现了alglib库(用于数值计算),这似乎是我正在寻找的东西(鲁棒插值,数据分析......),并且无法真正找到numpy或scipy.
但是,我担心(例如插值)它不接受numpy数组作为有效的输入格式,而只接受常规的python列表对象.
问题: 我在代码和文档中挖了一些,发现(正如预期的那样)这个列表格式只是用于转换,因为库无论如何都会将它转换为ctypes(cpython库只是底层C的接口)/C++库).
这就是我关注的地方:在我的代码中,我正在使用numpy数组,因为它对我正在进行的科学计算有很大的性能提升.因此,我担心必须将传递给alglib例程的任何数据转换为列表(将转换为ctypes)将对性能产生巨大影响(我正在使用可能内部有数十万个浮点数的数组,以及数千个阵列).
问题: 你认为我确实会有性能损失,或者你认为我应该开始修改alglib代码(只有python接口)以便它可以接受numpy数组,并且只进行一次转换(从numpy数组到ctypes )?我甚至不知道这是否可行,因为它是一个相当大的图书馆...也许你们有更好的想法或建议(即使在相似但不同的图书馆)......
看来我的问题没有得到很多兴趣,或者我的问题不明确/相关.或者也许没有人有解决方案或建议,但我怀疑周围有这么多专家:)无论如何,我写了一个小的,快速和脏的测试代码来说明问题......
#!/usr/bin/env python
import xalglib as al
import timeit
import numpy as np
def func(x):
return (3.14 *x**2.3 + x**3 -x**2.34 +x)/(1.+x)**2
def fa(x, y, val=3.14):
s = al.spline1dbuildakima(x, y)
return (al.spline1dcalc(s, val), func(val))
def fb(x, y, val=3.14):
_x = list(x)
_y = list(y)
s = al.spline1dbuildakima(_x, _y)
return (al.spline1dcalc(s, val), func(val))
ntot = 10000
maxi = 100
x = np.random.uniform(high=maxi, …Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的代码添加一些"插件"(我不确定这是否是正确的定义).通过"插件",我指的是一个定义模型(这是一个科学代码)的模块,它的存在足以在代码中的任何其他地方使用它.
当然,这些插件必须遵循一个模板,该模板使用我的代码中定义的一些模块/函数/类.以下是我的代码相关部分的小片段:
# [In the code]
class AllModels():
def __init__(self):
"""
Init.
"""
self.count = 0
def register(self, name, model):
"""
Adds a model to the code
"""
setattr(self, name, model)
self.count += 1
return
class Model():
def __init__(self, **kwargs):
"""
Some constants that defines a model
"""
self.a = kwargs.get("a", None)
self.b = kwargs.get("b", None)
# and so on...
def function1(self, *args, **kwargs):
"""
A function that all models will have, but which needs:
- to have a …Run Code Online (Sandbox Code Playgroud) 我已经阅读了有关__init__.py文件的文档以及关于SO的一些不错的问题,但是我仍然对其正确用法感到困惑。
我有一个包含许多程序包和子程序包的代码。我定义了许多类,其中一些我需要为整个用户会话创建一个(只有一个)实例。这些新对象然后在代码的不同部分中使用,因此,只要我(或用户)更新该对象中的数据/信息,便会在所有代码中使用它,而无需进行任何其他更改。更清楚地说,让我向您展示我所谈论的基本方案。
该代码的结构过于简化:
root/
__init__.py
tools/
__init__.py
... (some modules)
aliases.py (which defines the class Aliases)
physics/
__init__.py
... (some modules)
constants/
... (some modules)
constants.py (which defines the class Ctes)
units.py (which defines the class Units)
Run Code Online (Sandbox Code Playgroud)
在代码中,我需要管理别名,单位和常量。我发现处理该问题的方法是为每个实例创建一个实例,并在所有代码中使用它。例如,通过这种方法,我可以确定,如果在代码仍在运行时添加了别名,则可以在代码的任何位置使用它,因为只有一个共享的别名实例。这就是我所需要的(顺便说一句,单位和常量也是如此)。
就目前而言,我认为这不是最好的方法。确实,我在声明该类之后,在同一个文件中直接创建了别名的实例,例如别名:
在 root/tools/aliases.py
import ... (stuff
class Aliases(object):
"""The Aliases manager"""
...
ALIASES = Aliases()
Run Code Online (Sandbox Code Playgroud)
然后,在需要使用Aliase的任何文件中,我都执行以下操作:
在any_file.py(代码中的任何位置)
from root.tools.aliases import ALIASES
ALIASES.method1() # possibly in functions or other classes
ALIASES.method2() # ... etc
Run Code Online (Sandbox Code Playgroud)
对于其他一些类,我什__init__.py至在代码的根目录下使用该文件: …
[完全重写]
我正在寻找一种插值范围从 3 到 7 维的大数据集的方法。数据本质上是在非矩形网格上且不均匀间隔。
我查看了我能想到的所有选项(griddata、KDTree + magic、线性插值、重新设计的 map_coordinates...):最快和最有用的工具似乎是 Scipy 的 LinearNDInterpolator 函数。在如此高维空间中的线性插值很好,应该足够精确。
然而,这个类有一个很大的缺点:当我只想要插值时,带有间隙或“凹面区域”的数据会产生外推结果。
最好通过一些图片(二维测试)看到这一点。在下面,我为 X 和 VALUE 生成一些随机生成的数据,而 Y 的上限是 X 的函数(因此我创建了间隙)。

在重新缩放数据后(主要使用来自 master 的 LinearNDIterpolator 的代码段完成,即 development、branch),Delaunay 三角剖分将产生一个包含间隙的凸包,并将在该区域“外推”。从技术意义上讲,“外推”一词在这里并不真正正确,但我认为考虑到原始数据被认为是充分采样的事实,因此大差距意味着“不允许数据”(不是物理数据)这一事实是合适的。
为了开始处理这个问题,我“标记”了每个(超)体积高于用户定义阈值的德洛内(超)三角形(默认情况下,体积相当于每个维度中数据范围的 5%)。
生成随机数据并使用此技术评估值将产生下图:

黑点(带有红色或白色环)是要评估的随机生成的数据。红环表示我的基于 LinearNDInterpolator 的自定义类被拒绝的点(即值 = NaN),白环表示接受的点。为清楚起见,我绘制了被原始 Delaunay 三角剖分拒绝的三角形。
如您所见,仍有一些白色环点落在间隙中,这是我不想要的。这是因为它们所属的单纯形体积小于授权的最大体积(其中一些三角形甚至在图中显示为线条,因此很难看到)
我的问题是:我怎样才能从这里改进?可以做什么?
我想抓住每个评估点周围的小球中的所有点,看看是否有点。但这不是一个好的解决方案,因为它会消耗资源并且不够精确(例如,非常接近间隙底部但在上限外的点呢?)
这是我使用的自定义插值模块:
#!/usr/bin/env python
"""
Custom N-D linear interpolation class, based on scipy's LinearNDInterpolator.
The main differences are:
- auto-scaling
- interpolation: inside convex hull (normal behavior), and "close enough" to original data.
This rejects points that …Run Code Online (Sandbox Code Playgroud) 我目前正在创建一个名为"SET"的代码.代码的名称是首字母缩略词,已经为许多(非编程)原因定义,因此无法更改.
问题:最简单的,我相信最终用户使用我的代码的痛苦方式就是命名包"set".但当然这是一个问题,因为这与内置的set函数冲突.
问题:有哪些可能的解决方案?有些可能(可能更多):
更改包名称(例如setb).
import setb
Run Code Online (Sandbox Code Playgroud)
我真的不愿意,因为那时它会与真实姓名不同
使包的名称大写(SET)
import SET
Run Code Online (Sandbox Code Playgroud)
这将是一个直接的解决方案,但我想知道:这是一个pythonic正确命名的包?此外,我发现这有点痛苦,因为代码中定义的所有模块都会有类似"import SET.xy .."(即大写,写了很多次).但如果这是一种pythonic方式,这不是什么大问题.
保持名称"设置"
import set
Run Code Online (Sandbox Code Playgroud)
那显然不是很好.但只有当用户使用"导入集"时才会出现问题,不是吗?这不应该发生在"正常使用条件"中,因为代码将提供一些脚本来使用它,而不是将它用作标准的python模块.但我们永远不知道,它可以像它一样导入,甚至可能有一些我没有看到的问题(使用内置的设置).
我正在考虑解决方案2.但我真的不确定.也许这不合适,或者你们有更好的解决方案.
PS:我在网络和stackoverflow上发现了一些类似的主题,但它通常处理包内的脚本或模块内的名称.这里的问题实际上与代码的名称有关(只有这样才有意义),因此与包名称的正确命名有关.
编辑
选择的解决方案:我选择使用"SET"作为包名.虽然这里提出了许多好的建议:pyset,semt,setool ......或更明确的"starexoplanettool"(解释缩写).谢谢大家.
编辑#2
我喜欢有趣的解决方案:拥有一个名为S的包,以及一个子包,E ...最终得到:
import S.E.T
Run Code Online (Sandbox Code Playgroud)
谢谢唐问题.