如何在子 class 中使用父 class 的属性?

How can use an attribute from parent class in a child class?

我是 Python 的 OOP 初学者。这是我的代码块。

#%% IMPORTING MODULES
import numpy as np
import netCDF4 as nc4
import datetime as dt

#%% RAINFALL CLASS
class Rainfall():
    date_zero = dt.date(1901,1,1)

    #Initialise the class attributes
    def __init__(self,path):
        self.path = path
        self.dataset = nc4.Dataset(self.path, mode='r')
        self.lon = self.dataset.variables['LON'][:]
        self.lat = self.dataset.variables['LAT'][:]
        self.time = self.dataset.variables['TIME'][:]
        # self.rf = self.dataset.variables['RAIN'][:]
        self.date = np.arange(dt.datetime(1979,1,1), dt.datetime(2019,1,1), dt.timedelta(days=1)).astype(dt.datetime)
        self.index_jjas = []
        for i,val in enumerate(self.date):
            if val.month >= 6 and val.month<=9:
                self.index_jjas.append(i)
        self.jjas_rf = self.dataset.variables['RAIN'][self.index_jjas]
        self.nonzero = self.nonzero_jjas()
        self.sorted_rf = self.sorted_list(self.nonzero)
        self.threshold = self.p95(self.sorted_rf)
        self.val_abv_threshold = np.ma.masked_less(self.nonzero, self.threshold)
        self.abv_threshold = np.ma.MaskedArray.count(self.val_abv_threshold, axis=0)
        self.clim = self.simpleprob(self.abv_threshold, len(self.index_jjas))

    #Method to find the non zero precipitation
    def nonzero_jjas(self):
        return np.ma.masked_less(self.jjas_rf, 0.2)

    #Method to sort the non zero precipitation array
    def sorted_list(self, nz):
        return np.ma.MaskedArray.filled(np.ma.sort(nz, axis=0), np.nan)

    #Method to obtain the 95th percentile for threshold value to identify extremes
    def p95(self,ns):
        return np.nanpercentile(ns, 95, axis=0)

    #Method to obtain the probabiltiy
    def simpleprob(self, a1, a2):
        return np.divide(a1, a2)

    #Method to identify ExtremeDays in Waves
    def extr(self, a1, a2, data, clim):
        m1 = a1.mask
        m2 = a2.mask
        m3 = m1 | m2
        count = np.ma.MaskedArray.count(a2, axis=0)
        data_new = np.ma.masked_where(m3, data)
        data_count = np.ma.MaskedArray.count(data_new, axis=0)
        data_prob = np.divide(data_count, count)
        prob_diff = data_prob - clim
        return (data_new, data_count, data_prob, prob_diff)
#%% Waves Class
class Waves(Rainfall):


    #Initialise the class attributes
    def __init__(self, path1, path2):
        self.olr_path = path1
        self.mvr_path = path2
        self.olr_dataset = nc4.Dataset(self.olr_path, mode='r')
        self.mvr_dataset = nc4.Dataset(self.mvr_path, mode='r')
        self.date = np.arange(dt.datetime(1979,1,1), dt.datetime(2019,1,1), dt.timedelta(days=1)).astype(dt.datetime)
        self.index_jjas = []
        for i,val in enumerate(self.date):
            if val.month >= 6 and val.month<=9:
                self.index_jjas.append(i)
        self.olr = self.olr_dataset.variables['olr'][self.index_jjas]
        self.mvr = self.mvr_dataset.variables['var'][self.index_jjas]
        self.mn_mvr = np.nanmean(self.mvr, axis=0)
        self.std_olr = np.nanstd(self.olr, axis=0)
        self.active = self.active_days()
        self.dry = self.dry_days(self.active)
        self.wet = self.wet_days(self.active)
        self.ext_dry = self.extr(self.val_abv_threshold, self.dry, self.olr, self.clim)
        self.ext_wet = self.extr(self.val_abv_threshold, self.wet, self.olr, self.clim)

    #Method to find the active days
    def active_days(self):
        return np.ma.masked_where(np.ma.getmask(np.ma.masked_less(self.mvr, self.mn_mvr)), self.olr)

    #Method to find the dry days
    def dry_days(self, act1):
        return np.ma.masked_less_equal(act1, (0.5*self.std_olr))

    #Method to find the wet days
    def wet_days(self, act1):
        return np.ma.masked_greater_equal(act1, (-0.5*self.std_olr))


#%% Create Objects and other attributes
rain = Rainfall(path='rf_1979_2018.nc')
mjo = Waves(path1='/home/anik3t/Documents/Data/olr/0.25degfiles/mjo_final.nc', path2= '/home/anik3t/Documents/Data/olr/mjo_var.nc')

我需要从子 Waves class 中的父 Rainfall class 访问 val_abv_threshold,但我无法访问。 运行 代码给出了以下错误消息:

Traceback (most recent call last):

  File "/home/anik3t/.config/spyder-py3/test_run1.py", line 109, in <module>
    mjo = Waves(path1='/home/anik3t/Documents/Data/olr/0.25degfiles/mjo_final.nc', path2= '/home/anik3t/Documents/Data/olr/mjo_var.nc')

  File "/home/anik3t/.config/spyder-py3/test_run1.py", line 91, in __init__
    self.ext_dry = self.extr(self.val_abv_threshold, self.dry, self.olr, self.clim)

AttributeError: 'Waves' object has no attribute 'val_abv_threshold'

我认为 Waves class 无法从父 class 访问所需的属性。我试图使用 super() 函数,但我不确定在这里应该如何使用它。

您需要致电:

super().__init__(<some path>)

Waves class 的构造函数调用其父 class 的构造函数。否则该代码将不会被执行。

当你有 child class 时,你必须在 __init__ 方法中创建 parent class object child class。在您的代码中,parent class __init__ 方法需要一个参数 (path),您应该在创建 parent object 时传递该参数。您可以通过添加以下行来完成此操作:

super().__init__(path)

这里的路径和你创建的Rainfallobject一样,对应Wave

rain = Rainfall(path=some_path)

如果 Rainfall 和 Wave 完全不同并且它们不共享属性 path,您可以使用两个 children classes 作为替代选项以下:

Class Parent:
   def __init__(self):
       ## define your parent class attributes

   def Method1(self, args):
       ## define your parent class method

   def Method2(self, args):
       ## define your parent class method


Class Child1:
   def __init__(self):
       super().__init__()
       ## define your parent class attributes

   def Method3(self, args):
       ## define your parent class method

   def Method4(self, args):
       ## define your parent class method

Class Child2:
   def __init__(self):
       super().__init__()
       ## define your parent class attributes

   def Method3(self, args):
       ## define your parent class method

   def Method4(self, args):
       ## define your parent class method

这样你的 child1 class 可以是 RainfallChild2 可以是 Wave 所有共享的属性和方法都将在 Parent class.