Python 在不定义类的情况下,是否可以编写一个以“self”作为参数的函数?

Python 在不定义类的情况下,是否可以编写一个以“self”作为参数的函数?,python,function,oop,object,self,Python,Function,Oop,Object,Self,我试图通过实现函数来减少一些代码行。我正在研究将自身作为参数的函数,如oop中的函数。例如: def drop_columns(self, columns): return self.drop(columns, axis = 1) df.drop_columns(['id', 'date']) 或 当然,更复杂。但是,该代码不起作用。如果我向它提供一个数据帧,它会抛出一个错误: AttributeError:“DataFrame”对象没有属性“print\u shape” 有什么方法

我试图通过实现函数来减少一些代码行。我正在研究将自身作为参数的函数,如oop中的函数。例如:

def drop_columns(self, columns):
    return self.drop(columns, axis = 1)

df.drop_columns(['id', 'date'])

当然,更复杂。但是,该代码不起作用。如果我向它提供一个数据帧,它会抛出一个错误: AttributeError:“DataFrame”对象没有属性“print\u shape”


有什么方法可以实现这一点吗?

在类的实例上调用方法时,该实例将自身作为第一个参数传递。为了方便起见,我们通常称这个参数为self

这仅在方法首先绑定到实例时有效。当您执行df.print_shape时,它不起作用,因为您从未以任何方式将print_shape附加到df

不过,以下两项都将起作用:

# approach 1: call it as a function
print_shape(df)

# approach 2: assign the function as an attribute of df, then call it as a method
setattr(df, 'print_shape', print_shape)
df.print_shape()

方法1是首选方法,因为通常更好的做法是不要修改不是自己创建的对象,也不要像这样动态地修改对象。但是知道了方法2的存在,就可以对python作为一种语言的工作方式有一些透视/洞察。如果您坐在print_shape内部,无法查看外部的任何情况,则无法区分这两种方法之间的区别。

当您对类的实例调用方法时,该实例将自身作为第一个参数传递。为了方便起见,我们通常称这个参数为self

这仅在方法首先绑定到实例时有效。当您执行df.print_shape时,它不起作用,因为您从未以任何方式将print_shape附加到df

不过,以下两项都将起作用:

# approach 1: call it as a function
print_shape(df)

# approach 2: assign the function as an attribute of df, then call it as a method
setattr(df, 'print_shape', print_shape)
df.print_shape()

方法1是首选方法,因为通常更好的做法是不要修改不是自己创建的对象,也不要像这样动态地修改对象。但是知道了方法2的存在,就可以对python作为一种语言的工作方式有一些透视/洞察。如果你坐在print_shape内部,看不到它之外的任何东西,你就无法分辨这两种方法之间的区别。

我认为你把类和OOP与函数混淆了。在您的情况下,不要将输入视为对象,而应将参数视为函数:

drop_columns(df, ['id', 'date'])
print_shape(df)

这些调用应该可以工作。

我认为您将类和OOP与函数混淆了。在您的情况下,不要将输入视为对象,而应将参数视为函数:

drop_columns(df, ['id', 'date'])
print_shape(df)

这些调用应该有效。

以第二个示例为例。。。您可以做的是:

    def __init__(self, shape=None):
        self.shape = shape
现在,将print_shapeShape或print_shapeShape称为“圆圈”


由于打印形状不绑定到任何类或对象,因此它可以将self视为一个参数。

以第二个示例为例。。。您可以做的是:

    def __init__(self, shape=None):
        self.shape = shape
现在,将print_shapeShape或print_shapeShape称为“圆圈”


由于打印形状未绑定到任何类或对象,因此它可以将self视为一个参数。

这里的另一种方法是从DataFrame中创建子类,并在此类中构建方便的函数:

import pandas as pd
import numpy as np

class EnhancedDataFrame(pd.DataFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    def print_shape(self):
        print(self.shape)
    def print_foo(self):
        print('This is the \'foo\'')

data = np.array(np.random.randint(0,100,(3,4)))
columns = ['A','B','A','C']
index = ['Row 1', 'Row 2', 'Row 3']
frame = EnhancedDataFrame(data, index=index, columns=columns)
然后你应该能够做到:

因此,找到问题的根源:

但是,该代码不起作用。如果我给它一个数据帧,它会抛出一个错误:AttributeError:“DataFrame”对象没有属性“print\u shape”

我们现在已经实现了我们自己的类EnhancedDataFrame,它是一个数据帧,好吧,从技术上讲它继承自数据帧。它实现了您通常期望在数据帧中使用的所有方法,但现在还包括您可能希望添加的任何方便方法


这里的另一种方法是从DataFrame中生成子类,并在此类中构建方便的函数:

import pandas as pd
import numpy as np

class EnhancedDataFrame(pd.DataFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    def print_shape(self):
        print(self.shape)
    def print_foo(self):
        print('This is the \'foo\'')

data = np.array(np.random.randint(0,100,(3,4)))
columns = ['A','B','A','C']
index = ['Row 1', 'Row 2', 'Row 3']
frame = EnhancedDataFrame(data, index=index, columns=columns)
然后你应该能够做到:

因此,找到问题的根源:

但是,该代码不起作用。如果我给它一个数据帧,它会抛出一个错误:AttributeError:“DataFrame”对象没有属性“print\u shape”

我们现在已经实现了我们自己的类EnhancedDataFrame,它是一个数据帧,好吧,从技术上讲它继承自数据帧。它实现了您通常期望在数据帧中使用的所有方法,但现在还包括您可能希望添加的任何方便方法


您可以根据需要命名函数的参数;从类实例方法检索到的函数的行为与特定名称self完全无关。当然,您可以将print_shapedf作为实用函数来执行。或者您可以将DataFrame子类化您可以根据需要命名函数的参数;从类实例方法检索的函数的行为与特定名称self完全无关。当然,您可以将print_shapedf作为实用函数来执行。或者您可以将DataFrameThank子类化。谢谢!后续问题:是否可以映射对象方法,如drop,例如mapdrop['column',axis=1,df?我正在寻找一个简洁的解决方案,从多个数据帧中删除列。不是直接删除,但您可以
可能使用lambda函数来解决问题,例如maplambda d:dropd、['column']、axis=1、df或其他。map的问题是它只传递一个参数,所以如果您想调用具有多个参数的对象,您必须以lambda的形式进行调用。谢谢!后续问题:是否可以映射对象方法,如drop,例如mapdrop['column',axis=1,df?我正在寻找一种从多个数据帧中删除列的简明解决方案。不是直接删除,但您可以使用lambda函数进行解决,例如maplambda d:dropd、['column'],axis=1、df或其他。map的问题是它只传递一个参数,所以如果您想调用具有多个参数的对象,您必须以lambda的形式进行调用。