代码之家  ›  专栏  ›  技术社区  ›  00schneider

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

  •  1
  • 00schneider  · 技术社区  · 5 年前

    我试图通过实现函数来减少一些代码行。我在研究那些把自己当作参数的函数,就像在oop中一样。例如:

    def drop_columns(self, columns):
        return self.drop(columns, axis = 1)
    
    df.drop_columns(['id', 'date'])
    

    def print_shape(self):
        print(self.shape)
    
    df.print_shape()
    

    当然更复杂。但是,代码不起作用。如果我给它一个数据帧,它会抛出一个错误: AttributeError: 'DataFrame' object has no attribute 'print_shape'

    有办法让这一切顺利吗?

    2 回复  |  直到 5 年前
        1
  •  3
  •   Green Cloak Guy    5 年前

    对类的实例调用方法时,该实例将自身作为第一个参数传递。我们通常称之为参数 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作为一种语言的工作方式有一些透视/洞察。如果你坐在里面 打印形状() ,看不到外面发生的任何事情,就无法区分这两种方法的区别。

        2
  •  2
  •   FatihAkici    5 年前

    我认为你把类和面向对象编程与函数混淆了。在您的示例中,不要将输入视为对象,而应将参数视为函数:

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

    这些电话应该有用。

        3
  •  1
  •   David Zemens    5 年前

    这里的另一种方法是从 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)
    

    然后你应该可以这样做:

    enter image description here

    所以要找出问题的根源:

    但是,代码不起作用。如果我给它一个数据帧,它会抛出一个错误: AttributeError: 'DataFrame' object has no attribute 'print_shape'

    我们现在已经实现了自己的类( EnhancedDataFrame 哪一个? 数据文件 (好吧,好吧,从技术上讲它继承自 数据文件 )。它实现了通常在 数据文件 ,但现在还包括您可能要添加的任何便利方法!

    enter image description here

        4
  •  0
  •   Bugs Buggy    5 年前

    举第二个例子…你能做的是:

        def __init__(self, shape=None):
            self.shape = shape
    

    现在,呼叫 print_shape(Shape()) print_shape(Shape('circle')) .

    由于print shape没有绑定到任何类(或对象),因此它可以将self视为参数。