Переменные экземпляра похожи на ограниченную форму глобальной переменной. Каждый экземпляр можно рассматривать как автономную (предназначенную для каламбура) область, которая передается как явный аргумент функции. Без класса вы бы просто передавали каждую общую переменную явно, а не неявно, как часть аргумента self
.
def isValidBST(root, lastVal, isBST):
lastVal = - 2**32
self.isBST = True
lastVal, isBST = valid(root, lastVal, isBST)
return lastVal, isBST
def valid(node, lastVal, isBST):
if node is None:
return lastVal, isBST
lastVal, isBST = valid(node.left, lastVal, isBST)
if lastVal >= node.val:
isBST = None
return lastVal, isBST
lastVal = node.val
lastVal, isBST = valid(node.right, lastVal, isBST)
return lastVal, isBST
Ясно, что в приведенном выше описании есть место для упрощения: isValidBST
на самом деле не нужно принимать дополнительные аргументы, поскольку он игнорирует их и устанавливает их явно; вы можете просто использовать return valid(root, lastVal, isBST)
вместо распаковки возвращаемого значения и повторной упаковки для возврата значений; и т.д. Но идея есть: глобальные переменные могут быть заменены явными аргументами функции и возвращаемыми значениями.
Если вы изучите такой язык, как Haskell, вы обнаружите монаду State
, которая является способом абстрагирования повторения передачи глобального состояния таким образом и написания кода, который «выглядит» так, как будто он использует глобальные переменные .