从Python中的另一个函数调用变量



在过去的几个小时里,我一直在四处阅读,但我并没有真正理解我确信的一个非常基本的概念:在不同的函数之间传递值(作为变量(。

class BinSearch:
def __init__(self,length,leng,r,obj_function,middle):
self.length = length
self.leng = leng
self.r = r
self.obj_function = obj_function
self.middle = middle
self.objtobin(obj_function)
def BinarySearch(length,leng,r):
mid = np.arange(0,len(length),1)
middle = min(mid) + (max(mid)-min(mid))//2
L_size = []
L = length[middle]
L_size.append(L)
return L
def objtobin(self,obj_function):
# length,leng,middle = BinSearch.BinarySearch()
if (obj_function>=0.98):
return BinSearch.BinarySearch(self.length,min(leng),self.middle-1)
else:
return BinSearch.BinarySearch(self.length,self.middle+1,max(leng))
BinSearch.objtobin(obj_function=max(objectivelist))

当我运行上面的代码时,BinSearch.objtobin代码给出了"objtobin((缺少1个必需的位置参数:'self'",我该如何处理这个错误?谢谢你的帮助!

首先,感谢大家的帮助。但我不明白我应该如何更改这个代码

我已经开始修改您的代码,使其运行时不会出错,但其中也有一些其他错误,我还没有试图理解您的所有参数。

它看起来像这样,但我将在下面解释。

# --- OP's attempt that fails ---
# BinSearch.objtobin(obj_function=max(objectivelist))
# -- -- -- -- -- -- -- -- -- -- --
# --- Using an instance ---
figure_this_out_yourself = 100
# this variable is a placeholder for any parameters I had to supply
myBinSearchInstance = BinSearch(
length = figure_this_out_yourself,
leng = [figure_this_out_yourself],
r = figure_this_out_yourself,
obj_function = figure_this_out_yourself,
middle = figure_this_out_yourself)
myBinSearchInstance.objtobin(obj_function = max(objectivelist))

这里有一个重要的概念需要掌握:self

让我们在这里考虑这个简单的示例函数,它将始终输出比上次大一的数字。

counter = 0
def our_function ():
global counter
counter = counter + 1
return counter
print(our_function())

这是可以的,但它使用全局变量来跟踪其状态。想象一下,将它同时用于两个不同的目的。那将是一片混乱!因此,我们将其封装在一个类中。

# unfinished apprach
counter = 0
class OurClass:
# This is called a static method
def our_function ():
global counter
counter = counter + 1
return counter
print(our_function())

当我们试图运行这个时,我们遇到了一个问题。

NameError:名称our_function未定义

之所以会发生这种情况,是因为它现在只能在该类中访问。所以我们需要称之为

print(OurClass.our_function())

这使得使用相同名称的函数是可以的——只要它们在不同的类中——但这并不能解决我们一次多次使用our_function的混乱问题。我们想要的基本上是有两个独立的counter变量。这就是实例发挥作用的地方:当然,我们可以手动创建第二个使用第二个全局变量的函数,但当你越来越多地使用它时,它很快就会失控。

让我们在课堂上移动counter

class OurClass:
counter = 0
def our_function ():
global counter
counter = counter + 1
return counter

你猜对了-现在counter不再被定义:

NameError:名称counter未定义

因此,让我们将要使用的实例变量作为参数传递到函数中。然后使用该实例获取其计数器:

class OurClass:
counter = 0
def our_function (the_instance):  
the_instance.counter = the_instance.counter + 1
return the_instance.counter
myInstance = OurClass()
mySecondInstance = OurClass()
print(OurClass.our_function(myInstance))
print(OurClass.our_function(mySecondInstance))

并且成功地,两个打印语句都打印了1

但这有点烦人,因为这个the_instance与其他论点不同。为了使其与众不同,python允许我们避免使用第一个参数,而是将其作为接收器提供。这两项工作:

print(myInstance.our_function())
print(OurClass.our_function(mySecondInstance))

Python对这些参数使用非常强的约定。将其称为self,而不是the_instance。参见为什么自我只是一种惯例?。

class OurClass:
counter = 0
def our_function (self):  
self.counter = self.counter + 1
return self.counter
myInstance = OurClass()
mySecondInstance = OurClass()
print(myInstance.our_function())
print(mySecondInstance.our_function())

现在我们差不多完成了!只剩下一件事需要理解:__init__()的参数来自哪里
它们从我们构造它的行传递到__init__()。因此,让我通过添加counter的起始值来演示:

class OurClass:
counter = 0
def __init__ (self, starting_value):
self.counter = starting_value
def our_function (self):  
self.counter = self.counter + 1
return self.counter
myInstance = OurClass(5)
mySecondInstance = OurClass(10)
print(myInstance.our_function())
print(OurClass.our_function(mySecondInstance))

这将打印611


但这些评论对@staticmethod意味着什么?为此,请参阅staticmethod和classmethod之间的区别以及我们真的需要python中的@staticmethod装饰器来声明静态方法吗。
简而言之:您可以用@staticmethod@classmethod注释类中的任何方法。

  • @staticmethod意味着当OurClass.foo()不以self为参数时,它可以像myInstance.foo()一样被调用。如果没有这个decorator,您只能将其称为OurClass.foo(),而不能将其命名为myInstance.foo()
  • @classmethod意味着它可以像myInstance.foo()一样被调用,并且它没有得到myInstance作为第一个参数,而是得到myInstance的类,即OurClass。这允许您定义替代构造函数。此外,类方法在子类化时不会被继承,因此不会被错误地调用

注释指出,您也可以使用@staticmethod并避免创建实例。为此,您不必在类本身中使用任何变量,但无论如何,您不会长时间使用这些变量,因此您可以将它们作为参数传递给函数。

最新更新