为啥你不能命名一个在函数中创建的对象,与它在 Python 中的类名完全相同?

Posted

技术标签:

【中文标题】为啥你不能命名一个在函数中创建的对象,与它在 Python 中的类名完全相同?【英文标题】:Why can't you name an object, which is created in a function, exactly the same as it's class-name in Python?为什么你不能命名一个在函数中创建的对象,与它在 Python 中的类名完全相同? 【发布时间】:2020-06-28 19:29:06 【问题描述】:

我正在 Jupyter 笔记本中编写 Black Jack 游戏,为此我有一个“玩家”和一个“经销商”类,还有一个基本上运行整个游戏的函数 (BlackJack())。

def BlackJack():   
    name = input("What is your name: ")
    while True:
        try:            
            money = int(input(f"Welcome to our casino Black Jack game name!How big is your balance in € : "))
        except ValueError:
            print("Just give me a number: ")
        else:
            print("Ok, let's start!")
            break
    player = player(name, money) # player() class
    dealer = dealer()            # dealer() class

当我尝试创建与类本身同名的类对象时发生错误:

错误信息:

What is your name: "Richard"
Welcome to our casino Black Jack game "Richard"!How big is your balance in € : 19163
Ok, let's start!
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-55-3c92f609e237> in <module>
----> 1 BlackJack()

<ipython-input-54-57fc63786581> in BlackJack()
      9             print("Ok, let's start!")
     10             break
---> 11     player = player(name, money)
     12     dealer = dealer()

UnboundLocalError: local variable 'player' referenced before assignment

但是如果我将类对象命名为不同的或者我将它们命名为相同的,但在函数之外没有错误:

def BlackJack():   
    name = input("What is your name: ")
    while True:
        try:            
            money = int(input(f"Welcome to our casino Black Jack game name!How big is your balance in € : "))
        except ValueError:
            print("Just give me a number: ")
        else:
            print("Ok, Let's Start!")
            break
    plyr = player(name, money)
    dlr = dealer()

player = player("Jimmy", 1200)

是否只是因为在函数中 Python 认为我想在我分配变量之前为自己分配一个变量 (dealer = Dealer()),即使它们实际上并不相同,因为一个是变量和另一个是一个类?在这种情况下,Python 也只是忽略了一个事实,例如经销商()是一个类而不是变量“经销商”?

提前致谢!

P.S.:我使用 Python 3.7.4

【问题讨论】:

【参考方案1】:

在函数中的任何位置分配一个名称使其成为局部变量,除非该变量已在函数中声明为全局变量。在给它一个值之前尝试引用这个变量是错误的。

所以看看你的代码:

player = player(name, money)

名称player 是一个局部变量,还没有值。但是您正试图将其称为函数或类。你不能那样做。

如果您在左侧使用不同的名称,正如您所发现的,player 指的是您定义的类并且它有效。

这是(一个原因)使用大写的类名是标准的 Python 风格。这将解决问题并更清楚地表明您正在实例化一个类。

player = Player(name, money)

同样,因为BlackJack是一个函数,所以应该命名为blackjack

【讨论】:

好的,我明白了。因此,根据 LEGB-Rule (Local, Enclosure function local, Global, Built-in),它认为“player(name, money)”与局部变量“player”有关,与“player()”类无关" 本身,因为我在语句 "player = player(name, money)" 中“调用”了变量 "player" ? @MihailStefanov 否,因为您使用了使用该名称的赋值语句,所以 编译器 将其标记为本地。但即使在这种特殊情况下存在范围问题,您也不应该覆盖分配给该类的名称。 是的,player() 用于引用您尚未定义的局部变量 player。在 Python 中,类(和函数)的名称并没有什么特别之处。类只是变量可以引用的一种值。

以上是关于为啥你不能命名一个在函数中创建的对象,与它在 Python 中的类名完全相同?的主要内容,如果未能解决你的问题,请参考以下文章

你如何调用在javascript中的数组中创建的对象的函数?

C#winform中为啥一个窗体的对象可以调用在另一个窗体中创建的一个类未实例化下

在 pyqt 设计器中创建的对象上的 findChild

我在 vb6(winsock) 中创建的客户端/服务器程序不能在 WAN 上运行,但可以在 LAN 上完美运行 为啥?

Navicat 8 for MySQL中创建的表为啥在mysql数据库中没有

如何使在 ddply 中创建的对象在函数外部可用(在全局环境中)?