如何使用方法修改python中类的属性而不返回实例(就地操作)

2024-10-04 03:18:26 发布

您现在位置:Python中文网/ 问答频道 /正文

描述我的目标和问题:

我目前正在使用python中的scanpyanndata包(版本3.6.12)。如果您不熟悉这些包,只需知道anndata.AnnData在属性X中存储了一个数据矩阵(numpy.ndarray)。X的列在panda.DataFrame属性的var中描述,行在obs属性中描述。有关更多信息,请参见此link

我的目标是拥有一个从anndata.AnnData类继承的类(例如类a)。在这个子类中,我想实现一些处理方法,例如过滤掉某些行或列。 更重要的是,我还希望这些方法以“就地”的方式修改属性,而不需要返回副本(即不使用return self)。但是,当我删除方法中的return self时,类的实例不会被修改。更准确地说,self在函数内部被修改,但类的实例保持不变

代码示例:

想象一下下面的例子,类A继承自anndata.AnnData。类A有一个名为remove_last_row()的方法,该方法删除类A实例的最后一行(即obs)

import anndata
import numpy as np

class A(anndata.AnnData): 
    
    def __init__(self, adata, data_type=None): 
        """
        Initition method 
        
        Parameters: 
        -----------
        adata: anndata.AnnData, 
            The Anndata object
        """
        super().__init__(adata)
        
    def remove_last_row(self): 
        """
        Remove the last row of the anndata object
        """
        
        print("--> In A.remove_last_row() method:")
        print("before filtering: number rows = ", self.X.shape[0])
        
        # get the row index to keep (i.e. the index of the obs without the last one)
        index_to_keep = self.obs[:-1].values.astype(int)
        # Keep only those index: 
        self = self[index_to_keep, :]
        
        print("after filtering: number rows = ", self.X.shape[0])
        print("<-- exit A.remove_last_row() method.")

使用remove_last_row()方法时的问题是实例(self)的行在函数中被删除,但它不会修改类的实例。 请参见下面的示例:

# Create an AnnData object: 
adata = anndata.AnnData(np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]))
    
# Create object A that is inherited from AnnData
obj_A = A(adata = adata)
    
# Test remove_last_row method
obj_A.remove_last_row()

print()
print("obj_A.X attribute = \n", obj_A.X)

其结果是:

--> In A.remove_last_row() method:
before filtering: number rows = 3
after filtering: number rows = 2
<-- exit A.remove_last_row() method.

obj_A.X attribute =
[[0. 0. 0.]
[1. 1. 1.]
[2. 2. 2.]]

我们看到在remove_last_row()方法中,最后一行在函数内的self中被删除。但是obj_A(类A的实例)不会被此方法修改。如何在不添加return self的情况下解决此问题


其他信息:

  • Python版本=3.6.12
  • numpy版本=1.19.1
  • anndata版本=0.7.4
  • scanpy版本=1.6.0

我还测试了一个名为addition()的方法,它为数组X的每个元素添加了一个特定的值。用这种方法,我不会遇到这个问题

如果方法addition()在类A中:

   def addition(self, x=1): 
        """
        Add a value of x for each element in the X numpy array in the AnnData object
        
        Parameters: 
        -----------
        x: float,
            The value added to every element 
        """
        self.X += x

我们可以测试:

# Create an AnnData object: 
adata = anndata.AnnData(np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]))

# Create object A that is inherited from AnnData
print("Before addition")
obj_A = A(adata = adata)
print("obj_A.X attribute = \n", obj_A.X)

# Test the addition method
print()
obj_A.addition(x=1)
print()
print("After addition")
print("obj_A.X attribute = \n", obj_A.X)

结果是:

Before addition
obj_A.X attribute =
[[0. 0. 0.]
[1. 1. 1.]
[2. 2. 2.]]

After addition
obj_A.X attribute =
[[1. 1. 1.]
[2. 2. 2.]
[3. 3. 3.]]

如您所见addition()方法有效。它能够修改类的实例


Tags: the实例方法selfobjobjectmethodremove