我的目标是减少我创建的类中的一些冗余。我已将问题简化为一个非常简单的例子
class BigNumbers(object):
def __init__(self, big_number):
self.number = big_number
@classmethod
def make_with_sums(cls, sum_to):
fin_num = 0
for i in range(1, sum_to):
fin_num += i
return cls( fin_num )
@classmethod
def make_with_product(cls, mul_to):
fin_num = 1
for i in range(1, mul_to):
fin_num *= i
return cls( fin_num )
class dnryNumbers(object):
def __init__(self, big_number):
self.number = big_number
@classmethod
def _make_with_helper(cls, make_meth, fin_num):
method_dict = {'sum': lambda x, y: x + y,
'prod': lambda x, y: x * y
}
var = 0
for i in range(1, fin_num):
var = method_dict[make_meth](var, i)
return cls( var )
def make_with_sums(self, sum_to):
return self._make_with_helper( 'sum', sum_to )
def make_with_product(self, mul_to):
return self._make_with_helper('prod', mul_to )
我的目标是使用与使用BigNumbers
类时相同的函数调用,例如:
In [60]: bn = BigNumbers.make_with_product(10)
In [61]: bn.number
Out[61]: 362880
- 或 -
In [63]: bn = BigNumbers.make_with_sums(10)
In [64]: bn.number
Out[64]: 45
但目前的功能不起作用:
In [65]: bn = dnryNumbers.make_with_product(10)
TypeError: unbound method make_with_product() must be called with dnryNumbers instance as first argument (got int instance instead)
答案 0 :(得分:1)
简单的答案:make_with_sums
和make_with_products
是类方法,而不是实例方法,因此需要声明它们。另请注意,_make_with_helper
也需要将起始值作为参数;将var
初始化为0将使{{1}}返回make_with_product
,无论其参数是什么。
cls(0)
, method_dict
都是相同的字典,所以它应该是一个类变量:
_make_with_helper
但是现在,class dnryNumbers(object):
def __init__(self, big_number):
self.number = big_number
method_dict = {'sum': lambda x, y: x + y,
'prod': lambda x, y: x * y
}
@classmethod
def _make_with_helper(cls, make_meth, fin_num, starting_value):
var = starting_value
for i in range(1, fin_num):
var = dnryNumbers.method_dict[make_meth](var, i)
return cls( var )
@classmethod
def make_with_sums(cls, sum_to):
return cls._make_with_helper('sum', sum_to, 0)
@classmethod
def make_with_product(cls, mul_to):
return cls._make_with_helper('prod', mul_to, 1)
只是添加了一个你不需要的额外的间接层。由于函数不打算在类之外使用,只需将它们定义为“私有”方法,并直接使用它们。
method_dict
@classmethod def make_with_sums(cls,sum_to): return cls._make_with_helper(dnryNumbers._sum,sum_to,0)
class dnryNumbers(object):
def __init__(self, big_number):
self.number = big_number
@staticmethod
def _sum(x, y):
return x + y
@staticmethod
def _prod(x, y):
return x * y
@classmethod
def _make_with_helper(cls, make_meth, fin_num, starting_value):
var = starting_value
for i in range(1, fin_num):
var = make_meth(var, i)
return cls(var)
最后,值得指出的是,除非您的真实代码比此处显示的示例更复杂, @classmethod
def make_with_product(cls, mul_to):
return cls._make_with_helper(dnryNumbers._prod, mul_to, 1)
已作为_sum
提供,operator.add
仅为_prod
,operator.mul
只是_make_with_helper
内置(或reduce
,如果是Python 3)的重新实现。
functools.reduce
答案 1 :(得分:0)
解决方案1:
bn = dnryNumbers(5)
bn.make_with_product(10)
解决方案2:
@classmethod
def make_with_product(cls, mul_to):
return cls._make_with_helper('prod', mul_to )