使用Python中

时间:2016-03-01 06:06:21

标签: python class

我开始为我的程序中应该使用的其中一个类编写草稿,我首先编写了这段代码:

import math
import numpy as np

R = 6.371e6

phi_src, theta_src = 10, 40
phi_det,theta_det = -21, 10

depth_src, depth_det = 0,0 # both on the surface

l = 0

class Trajectory:

    def __init__(self,
                 phi_src,
                 theta_src,
                 phi_det,
                 theta_det,
                 depth_src,
                 depth_det,
                 l):

        self.phi_src = phi_src
        self.theta_src = theta_src
        self.phi_det = phi_det
        self.theta_det = theta_det
        self.depth_src = depth_src
        self.depth_det = depth_det
        self.l = l
    @property

    def r(self):
        r_src = R - self.depth_src
        r_det = R - self.depth_det

        x_src = r_src * math.cos(self.phi_src) * math.cos(self.theta_src)
        y_src = r_src * math.cos(self.phi_src) * math.sin(self.theta_src)
        z_src = r_src * math.sin(self.phi_src)

        x_det = r_det * math.cos(self.phi_det) * math.cos(self.theta_det)
        y_det = r_det * math.cos(self.phi_det) * math.sin(self.theta_det)
        z_det = r_det * math.sin(self.phi_det)

        coord_src = np.array((x_src, y_src, z_src))
        coord_det = np.array((x_det, y_det, z_det))

        L = np.linalg.norm(coord_src - coord_det)

        return math.sqrt(r_src**2 + self.l * (1.0 - L - (r_src - r_det) * (r_src + r_det)/L))

    def phi(r):
        pass


trajectory = Trajectory(phi_src,theta_src,phi_det,theta_det,depth_src,depth_det,l)

print(trajectory.r)

然后意识到了

        r_src = R - self.depth_src
        r_det = R - self.depth_det

        x_src = r_src * math.cos(self.phi_src) * math.cos(self.theta_src)
        y_src = r_src * math.cos(self.phi_src) * math.sin(self.theta_src)
        z_src = r_src * math.sin(self.phi_src)

        x_det = r_det * math.cos(self.phi_det) * math.cos(self.theta_det)
        y_det = r_det * math.cos(self.phi_det) * math.sin(self.theta_det)
        z_det = r_det * math.sin(self.phi_det)

        coord_src = np.array((x_src, y_src, z_src))
        coord_det = np.array((x_det, y_det, z_det))

        L = np.linalg.norm(coord_src - coord_det)

部分对于所有类的方法都是通用的,因此在每种方法中无数次计算它都没有意义,这篇文章应该与所有方法共享。 最好的方法是什么?我是否必须将其置于__init__方法中?我听说在__init__方法中进行任何计算都不是一个好习惯。

2 个答案:

答案 0 :(得分:0)

在不依赖于对象本身状态的类中声明函数的常用方法是使用@staticmethod装饰器,然后使用函数定义。您只传递函数参数。

如果您需要使用类级别参数,请改用@classmethod并注意您将cls而不是self传递给该函数(可以使用任何变量,所以它确实没有没问题。关键是你现在正在访问类属性和方法而不是对象的属性和方法。

class Trajectory:
    c = 10  # <<< Class level property.

    def __init__(self):
        self.c = 5  # <<< Object level property.

    @staticmethod
    def foo(a, b):
        return a * b

    @classmethod
    def bar(cls, a, b):
        return cls.foo(a, b) * cls.c  # <<< References class level method and property.

    def baz(self, a, b):
        return self.foo(a, b) * self.c  # <<< References object level method and property.

t = Trajectory()

>>> t.foo(3, 5)
15

>>> t.bar(3, 5)
150

>>> t.baz(3, 5)
75

答案 1 :(得分:0)

嗯,不完全确定我是否得到了你想要的东西,但引用了你一点......

def r(self):
    r_src = R - self.depth_src
    r_det = R - self.depth_det

    ....
    L = np.linalg.norm(coord_src - coord_det)

这很常见,你说因为像 def r(self)这样的方法总是其中一些变量,比如 r_src L :< / p>

def r(self):
    return math.sqrt(r_src**2 + self.l * (1.0 - L - (r_src - r_det) * (r_src + r_det)/L))

这个,imho告诉我,如果你想重用那些计算,那么它们应该是__init __(或从__init__调用)的一部分。但大多数情况下,您需要将所有这些变量设置为 self

...whereever you compute them in a common location...



    self.r_src = R - self.depth_src
    self.r_det = R - self.depth_det

    ....
    self.L = np.linalg.norm(coord_src - coord_det)

请注意,由于您依赖于上面的实例变量,例如 self.depth_src ,因此该方法不能是类方法,它必须是实例方法。

现在,将其他方法更改为指向那些预先计算的属性。

def r(self):

    return math.sqrt(self.r_src**2 + self.l * (1.0 - self.L   ....

现在,您可以通过属性按需计算这些属性。但是如果你问一个相当基本的Python问题,我认为你是这样,那么后来担心优化,现在就做最简单的。即在__init__或从那里调用的方法中计算它们。

现在,有很好的理由将它们从init中分离出来,但它主要与代码清晰度和模块性有关。如果该代码块具有某些特定的数学/业务域含义,则创建一个适当命名的方法并从main调用它。

另一方面,一些IDE和代码分析器在查看__init__中的实例变量时更好地计算实例变量,并且Python是动态的,因为糟糕的东西需要他们可以得到的所有帮助。