2016-03-01 76 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是動態的,因爲它是窮人需要的所有幫助。