2016-03-01 77 views
0

我开始做一个草案,都应该在类别中的一个我PROGRAMM使用和我第一次写这段代码:共享一段代码有方法的类里面在Python

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__方法中进行任何计算并不是一个好习惯。

+0

如果这是一次性计算,我认为你可以把它放在'__init__'方法 – kvorobiev

+0

对于我来说,如果它像init之后的静态属性,你可以在'__init__'中编写代码或者为它们创建getters )。 – rrw

回答

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 
0

嗯,不能完全确定,如果我得到你想要的东西,但你引用一个有点...

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

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

这是常见的,你说是因为喜欢高清R(个体经营)方法总有一些这些变量,如r_src大号

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

此,我mho,告诉我,如果你想重用这些计算,那么它们应该是__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是动态的,因为它是穷人需要的所有帮助。