简体   繁体   English

将现有的 function 重新定义为 class 的方法

[英]re-defining an existing function as method of a class

I am learning to use classes.我正在学习使用类。 I want to create a class with several methods and attributes.我想用几个方法和属性创建一个 class。 In my case, some of the methods might be functions that I have written elsewhere in the code.就我而言,其中一些方法可能是我在代码中其他地方编写的函数。

Is it a good practice to re-define the functions as methods of the class like in the following example?将函数重新定义为 class 的方法是否是一种好习惯,如下例所示?

def f(x,b):
    return b*x

class Class1:
    def __init__(self,b):
        self.b=8.
    def f(self,x):
        return f(x,self.b) 


instance1=Class1(5)
print instance1.f(7.)

The code returns what it should, but is this the right way to do it or perhaps it is redundant or it might lead to troubles for larger codes?代码返回它应该返回的内容,但这是正确的方法吗?或者它可能是多余的,或者可能会导致更大的代码出现问题?

What is the right way to define methods using function written elsewhere?使用其他地方编写的 function 定义方法的正确方法是什么?

Functions...功能...

Consider the following group of functions:考虑以下一组函数:

def stack_push(stack, value):
    stack.append(value)

def stack_is_empty(stack):
    return len(stack) == 0

def stack_pop(stack):
    return stack.pop()

Together, they implement a stack in terms of a built-in list.它们一起根据内置列表实现堆栈。 As long as you don't interact with the list directly, the only thing they allow is adding values to one end, removing values from the same end, and testing if the stack is empty:只要您不直接与列表交互,它们唯一允许的就是将值添加到一端,从同一端删除值,并测试堆栈是否为空:

>>> s = []
>>> stack_push(s, 3)
>>> stack_push(s, 5)
>>> stack_push(s, 10)
>>> if not stack_is_empty(s): stack_pop(s)
10
>>> if not stack_is_empty(s): stack_pop(s)
5
>>> if not stack_is_empty(s): stack_pop(s)
3
>>> if not stack_is_empty(s): stack_pop(s)
>>>

... vs. Methods ...与方法

Notice that each function takes the same argument: a list being treated as a stack.请注意,每个 function 都采用相同的参数:将列表视为堆栈。 This is an indication that we can instead write a class the represents a stack, so that we don't need to maintain a list that could potentially be (mis)used outside of these three functions.这表明我们可以改为编写一个class来表示一个堆栈,这样我们就不需要维护一个可能在这三个函数之外(错误)使用的list It also guarantees that we start with an empty list for our new stack.它还保证我们从新堆栈的空列表开始。

class Stack:
    def __init__(self):
        self.data = []

    def push(self, value):
        self.data.append(value)

    def is_empty(self):
        return len(self.data) == 0

    def pop(self):
        return self.data.pop()

Now, we don't work with a list that supports all sorts of non-stack operations like indexing, iteration, and mutation at the beginning or middle of the list: we can only push, pop, and test for emptiness.现在,我们不使用在list的开头或中间支持各种非堆栈操作(如索引、迭代和变异)的列表:我们只能推送、弹出和测试空性。

>>> s = Stack()

Things like s[3] , s.insert(2, 9) , etc are not allowed.不允许使用s[3]s.insert(2, 9)等。

(Note that we aren't strictly prevented from using s.data directly, but it's considered bad practice to do so unless the class says it is OK to do so in its documentation. In this case, we do not allow that.) (请注意,我们并未严格禁止直接使用s.data ,但除非 class 在其文档中说可以这样做,否则我们认为这样做是不好的做法。在这种情况下,我们不允许这样做。)

We use these methods much like we used the stack_* functions.我们使用这些方法很像使用stack_*函数。

>>> s.push(3)
>>> s.push(5)
>>> s.push(10)
>>> if not s.is_empty(): s.pop()
10
>>> if not s.is_empty(): s.pop()
5
>>> if not s.is_empty(): s.pop()
3
>>> if not s.is_empty(): s.pop()
>>>

The difference is, we cannot "accidentally" use other list methods, because Stack does not expose them.不同之处在于,我们不能“意外”使用其他列表方法,因为Stack没有公开它们。

>>> s.insert(3, 9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Stack' object has no attribute 'insert'

Finally, note that we don't write our original stack_* functions and use them in the definition of the Stack class: there is no need;最后,注意我们没有编写我们原来的stack_*函数,并在Stack class的定义中使用它们:没有必要; we just define the methods explicitly inside the class statement.我们只是在class语句中明确定义方法。

# No.
class Stack:
    def push(self, value):
        stack_push(self.data, value)

We also don't continue to use the stack_* functions on an instance of Stack .我们也不会继续在Stack的实例上使用stack_*函数。

#  No no no!
>>> stack_is_empty(s.data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM