为什么要对全局变量进行“全局”处理?

时间:2019-07-03 20:40:25

标签: python python-3.x oop scope global

我正在构建一个简化的区块链应用程序。
我建立了自己的迭代器,并且可以正常工作。

这是我的代码:

# ---------- DEPENDENCIES AND OTHERS ----------
import datetime
blockchains = []
n = 0

# ---------- BLOCK CLASS ----------
class Block:
    def __init__(self, sender, money, receiver, previous_block=None):
        self.time = datetime.datetime.now()
        self.sender = sender
        self.money = money
        self.receiver = receiver
        self.previous_block = previous_block

    def __repr__(self):
        return f"""> NEW BLOCK:
Time: {self.time}
Sender: {self.sender}
Money: {self.money}
Receiver: {self.receiver}
"""


# ----------BLOCKCHAIN CLASS ----------
class Blockchain:
    def __init__(self):
        # Set "Tail Block" default as none. This will help identify if Blockchain is empty or not.
        self.tail_block = None
        # Check if there are any existing blockchains
        if not blockchains:
            self.name = input("Insert New Blockchain Name: ")
            blockchains.append(self)
        else:
            # Cycle to ensure new Blockchain has a unique name.
            valid_name = False
            while not valid_name:
                name = input("Insert New Blockchain Name: ")
                print()
                if any(blockchain.name == name for blockchain in blockchains):
                    print("Name already in use.\n")
                else:
                    valid_name = True
                    self.name = name
                    blockchains.append(self)

    def __iter__(self):
        return self

    def __next__(self):
        # If Blockchain is empty:
        if not self.tail_block:
            raise StopIteration
        # If Blockchain is not empty:
        else:
            """ 'n' counts what iteration of "__next__()" the program is in.
                Or in other words, how many times the "__next__()" function has been run."""
            global n
            n += 1
            # If it's the first "__next__()" iteration:
            if n == 1:
                return self.tail_block
            # If it's after the first "__next__()" iteration:
            else:
                current_block = self.tail_block
                for i in range(n-1):
                    current_block = current_block.previous_block
                if not current_block:
                    raise StopIteration
                else:
                    return current_block

    def __repr__(self):
        return f"{self.name}"

    def add_block(self, new_block_sender, new_block_money, new_block_receiver):
        # Check to see if Blockchain is empty
        if not self.tail_block:
            new_block = Block(new_block_sender, new_block_money, new_block_receiver)
        # If it's not empty, the new block's "previous block" will be the existing "tail block"
        else:
            new_block = Block(new_block_sender, new_block_money, new_block_receiver, self.tail_block)
        # Update "Tail Block" to the newly created block
        self.tail_block = new_block

    def view(self):
        if not self.tail_block:
            print("There are no Blocks in this Blockchain.\n")
        else:
            current_block = self.tail_block
            while True:
                print(current_block)
                if not current_block.previous_block:
                    break
                else:
                    current_block = current_block.previous_block


# ---------- TESTS ----------
# Testing my iterator with an empty Blockchain:
blockchain_1 = Blockchain()
for block in blockchain_1:
    print(block)

# Testing my iterator with non empty Blockchain:
blockchain_2 = Blockchain()
blockchain_2.add_block("António", 200000, "Tim")
blockchain_2.add_block("António", 100000, "Bob")
blockchain_2.add_block("António", 50000, "John")
blockchain_2.add_block("António", 50000, "Bill")
for block in blockchain_2:
    print(block)

在我的迭代器中,有一个名为n的变量。
我在程序开始时用n声明了n = 0,以使其成为全局变量。

因此,由于n是全局变量,所以我只需要在我的__next__()方法内使用代码n += 1对其进行递增。
但是,当我这样做时,我得到一个UnboundLocalError: enter image description here

经过实验,我发现如果在global n上方键入n +=1可以解决该问题: enter image description here 但是为什么呢?

自从我在程序开始时声明n = 0以来,n是否应该已经是全局变量了?
为什么n首先应该是全球性的,为什么我必须“重新全局化” n才能实现这项工作?

0 个答案:

没有答案