有什么惯用的方法可以向 Python 中的对象添加方法吗?
Is there any idiomatic way to add methods to object in Python?
例如,我必须用一些基本的数学运算来制作计算器:
class Power_calc():
def calculate(self, exp):
self.srt = exp.split(" ")
self.x = float(self.srt[0])
self.y = float(self.srt[2])
operand = self.srt[1]
if operand == '+':
return self.summ(self.x, self.y)
elif operand == "-":
return self.minus(self.x, self.y)
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
calc1 = Power_calc()
print calc1.calculate("3.2 + 6.0")
有什么方法可以像在 Javascript 中那样对字典中的所有计算器方法进行分组(下面的示例):
function powerCalculator() {
var methods = { //adding all methods here
'+': function(a, b) {
return a + b;
},
'-': function(a, b) {
return a - b;
}
};
this.calculate = function(expression) {
var arr = expression.split(' '),
a = +arr[0],
b = +arr[2],
operand = arr[1]
return methods[operand](a, b);
}
是的,你可以做到。 Python 函数是 first-class 对象,因此您可以像在 JavaScript.
中一样将它们存储在字典中
如果您想在线定义函数,可以使用 lambdas:
methods = {
'+': lambda a, b: a + b,
# ...
}
或者仅引用外部函数:
def plus(a, b): return a + b
methods = {
'+': plus,
# ...
}
请注意,方法只是包装函数(存储 self
引用);您可以在字典中使用 self.summ
和 self.minus
来存储绑定方法:
class Power_calc():
def calculate(self, exp):
methods = {
'+': self.summ,
'-': self.minus,
}
self.srt = exp.split(" ")
self.x = float(self.srt[0])
self.y = float(self.srt[2])
operand = self.srt[1]
return methods[operand](self.x, self.y)
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
更简单,你可以使用这里的operator
module进行预定义操作函数:
import operator
methods = {
'+': operator.add
# ...
}
你在 JS 中所做的不是添加方法,它只是创建一个从名称到函数的映射,然后你可以在 calculate
方法中显式使用它。您可以在 Python 中做完全相同的事情(并且使用更少的样板来启动):
class PowerCalculator(object):
methods = {
'+': (lambda a, b: a + b),
'-': (lambda a, b: a - b)
}
def calculate(self, expression):
arr = expression.split(' ')
a = float(arr[0])
b = float(arr[2])
op = arr[1] # note that this is the operator, not the operand
return self.methods[op](a, b)
这与您在 JS 中所做的完全不一样,但非常接近。在 JS 中,您正在创建一个范围,其中定义了 methods
变量,然后将原型的 calculate
方法定义为该范围内的闭包。虽然你 可以 在 Python 中这样做,但你不必这样做,因为你有 class
语句,它创建了一个专门用于定义方法和其他的范围class 中的属性,因此您可以正常定义 methods
并将其作为属性访问。
如果您真的想将 summ
和 minus
定义为方法而不是 lambda
的内联函数,您可以。但是,您可能希望它们是 @staticmethod
s — 毕竟,它们不会对 self
.
做任何事情
如果你真的想让它们成为普通方法,你甚至可以这样做。但是你在 dict 中拥有的将是未绑定的方法,这意味着你必须显式传递 self
来调用它们。像这样:
class PowerCalculator(object):
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
methods = {
'+': summ,
'-': minus
}
def calculate(self, expression):
arr = expression.split(' ')
a = float(arr[0])
b = float(arr[2])
op = arr[1] # note that this is the operator, not the operand
return self.methods[op](self, a, b)
但是增加这种额外的复杂性确实没有任何好处。
例如,我必须用一些基本的数学运算来制作计算器:
class Power_calc():
def calculate(self, exp):
self.srt = exp.split(" ")
self.x = float(self.srt[0])
self.y = float(self.srt[2])
operand = self.srt[1]
if operand == '+':
return self.summ(self.x, self.y)
elif operand == "-":
return self.minus(self.x, self.y)
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
calc1 = Power_calc()
print calc1.calculate("3.2 + 6.0")
有什么方法可以像在 Javascript 中那样对字典中的所有计算器方法进行分组(下面的示例):
function powerCalculator() {
var methods = { //adding all methods here
'+': function(a, b) {
return a + b;
},
'-': function(a, b) {
return a - b;
}
};
this.calculate = function(expression) {
var arr = expression.split(' '),
a = +arr[0],
b = +arr[2],
operand = arr[1]
return methods[operand](a, b);
}
是的,你可以做到。 Python 函数是 first-class 对象,因此您可以像在 JavaScript.
中一样将它们存储在字典中如果您想在线定义函数,可以使用 lambdas:
methods = {
'+': lambda a, b: a + b,
# ...
}
或者仅引用外部函数:
def plus(a, b): return a + b
methods = {
'+': plus,
# ...
}
请注意,方法只是包装函数(存储 self
引用);您可以在字典中使用 self.summ
和 self.minus
来存储绑定方法:
class Power_calc():
def calculate(self, exp):
methods = {
'+': self.summ,
'-': self.minus,
}
self.srt = exp.split(" ")
self.x = float(self.srt[0])
self.y = float(self.srt[2])
operand = self.srt[1]
return methods[operand](self.x, self.y)
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
更简单,你可以使用这里的operator
module进行预定义操作函数:
import operator
methods = {
'+': operator.add
# ...
}
你在 JS 中所做的不是添加方法,它只是创建一个从名称到函数的映射,然后你可以在 calculate
方法中显式使用它。您可以在 Python 中做完全相同的事情(并且使用更少的样板来启动):
class PowerCalculator(object):
methods = {
'+': (lambda a, b: a + b),
'-': (lambda a, b: a - b)
}
def calculate(self, expression):
arr = expression.split(' ')
a = float(arr[0])
b = float(arr[2])
op = arr[1] # note that this is the operator, not the operand
return self.methods[op](a, b)
这与您在 JS 中所做的完全不一样,但非常接近。在 JS 中,您正在创建一个范围,其中定义了 methods
变量,然后将原型的 calculate
方法定义为该范围内的闭包。虽然你 可以 在 Python 中这样做,但你不必这样做,因为你有 class
语句,它创建了一个专门用于定义方法和其他的范围class 中的属性,因此您可以正常定义 methods
并将其作为属性访问。
如果您真的想将 summ
和 minus
定义为方法而不是 lambda
的内联函数,您可以。但是,您可能希望它们是 @staticmethod
s — 毕竟,它们不会对 self
.
如果你真的想让它们成为普通方法,你甚至可以这样做。但是你在 dict 中拥有的将是未绑定的方法,这意味着你必须显式传递 self
来调用它们。像这样:
class PowerCalculator(object):
def summ(self, a, b):
return a + b
def minus(self, a, b):
return a - b
methods = {
'+': summ,
'-': minus
}
def calculate(self, expression):
arr = expression.split(' ')
a = float(arr[0])
b = float(arr[2])
op = arr[1] # note that this is the operator, not the operand
return self.methods[op](self, a, b)
但是增加这种额外的复杂性确实没有任何好处。