在Python中,为什么不';为所有导入的文件声明为全局namspace的t变量

在Python中,为什么不';为所有导入的文件声明为全局namspace的t变量,python,class,object,namespaces,python-import,Python,Class,Object,Namespaces,Python Import,在C和PHP中,如果我在一个文件中声明了一些变量,那么就包含它(在C中的PHP中,它是编译的二进制文件的一部分)。它只是工作。为什么这在python中不起作用 下面是我在PHP中可以做的事情 文件a.php $a=1; $b=2; 文件b.php function add(){ global $a,$b; return $a+$b; } 文件c.php require('a.php') require('b.php') echo add().PHP_EOL; 你3点回来 但是在

在C和PHP中,如果我在一个文件中声明了一些变量,那么就包含它(在C中的PHP中,它是编译的二进制文件的一部分)。它只是工作。为什么这在python中不起作用

下面是我在PHP中可以做的事情

文件a.php

$a=1;
$b=2;
文件b.php

function add(){
   global $a,$b;
   return $a+$b;
}
文件c.php

require('a.php')
require('b.php')
echo add().PHP_EOL;
你3点回来

但是在python中,如果我做了类似的事情,它会说变量是未定义的。 在data.py中,我创建了以下对象/类。它不是任何函数的一部分,此处的缩进反映了与文件本身相同的级别/范围

player=Player()
在textadventure.py中,我有以下代码

from data import *
from lib import *
在lib.py中,我有

def check_input(usr_input):
    inputs=usr_input.split(' ')
    verb=inputs[0]
    global player
    if len(inputs) >= 2:
        obj=inputs[1]
    else:
        obj=None

    if verb in verbs:
        if verb == 'move':
            player.location.move(obj)
        elif verb == 'look':
            look(obj)
    else:
        print('not valid')

def look(obj):
    global player
    current_room=player.location
    if obj is None:
        print(current_room.desc)
    else:
        if obj in current_room.items:
            print(current_room.items[obj].desc)
        elif obj in current_room.mobs:
            print(current_room.mobs[obj].desc)
然后我得到了以下错误

Traceback (most recent call last):
  File "text_adventure.py", line 84, in <module>
    main_loop()
  File "text_adventure.py", line 81, in main_loop
    check_input(usr_input)
  File "/home/macarthur/misc_proj/python_projects/text_adventure/lib.py", line 23, in check_input
    look(obj)
  File "/home/macarthur/misc_proj/python_projects/text_adventure/lib.py", line 48, in look
    current_room=player.location
NameError: name 'player' is not defined
templates.py

class Item:
    _id=0
    desc=''
    interaction=''
    location=None
    def __init__(self,desc=desc,interact=interaction,location=location):
        self.desc=desc
        self.interaction=interact
        self.location=location
        self._id=Item._id
        Item._id+=1
    def get_item(self,player):
        move_location(self,-1)
        print("You have grabbed {} and put it into your \033[1minventory".format(self.desc))

    def move_location(self,location):
        self.location=location

class Weapon(Item):
    damage=0
    desc='It is a weapon'
    def __init__(self,damage=damage,desc=desc):
        self.damage=damage
        self.desc=desc


class World():
    rooms={}
    def __init__(self):
        pass
    def add_room(self,room):
        self.rooms[(room.x,room.y)]=room

class Mailbox(Item):
    contains='letter'
    def __init__(self,contains=contains):
        Item.__init__(self)
        self.contains=contains

class Player:
    x=0
    y=0
    location=None
    weapon=None
    dead=False
    hp=10
    def __init__(self):
        self.x=0
        self.y=0
        self.weapon=None
        self.dead=False
        self.location=None
        self.hp=10

    def damaged(amount):
        self.hp=self.hp-amount

class Inventory(Player):
    items={}
    def __init__(self,items=items):
        self.items=items

    def add(self,item):
        self.items.append(item)

    def show(self):
        for item in self.items:
            print(item._id.desc)

    def use(self,item):
        if item in items:
            print(item.interaction)
        else:
            print("You don't have that item")

class Room:
    desc="You're in a room"
    items=None
    mobs=None
    x=0
    y=0
    _id=0
    exits={}
    def __init__(self,desc=desc,items=items,mobs=mobs,x=x,y=y,exits=exits):
        self.exits=exits
        self.desc=desc
        self.items=items
        self.mobs=mobs
        self.x=x
        self.y=y
        self._id=Room._id
        Room._id+=1

    def add_moves(self,moves=exits):
        self.exits.update(moves)

    def move(self,movement,player):
        selected_move=self.exits.get(movement,None)
        if  selected_move:
            player.location=selected_move
        else:
            return None


class Mob:
    _id = 0
    desc="You can't discern anything about it."
    interact="It just looks at you."
    room=None
    alive=True
    name='None'
    hp=5
    def __init__(self,desc=desc,interact=interact,alive=alive,name=name,hp=hp):
        self.name=name
        self.desc=desc
        self.interact=interact
        self._id=Mob.id
        Mob._id+=1
        self.alive=alive
        self.hp=hp

class Grue(Mob):
    def __init__(self):
        super().__init__(desc='A giant grue stands before you',interact='You were eaten by a grue',name='Grue',hp=10)

根据@JohnGordon,任何需要了解另一个模块(或脚本)中声明的变量/对象的模块(脚本)。您必须导入它,以便它了解它。全局名称空间不像PHP或其他语言那样是全局的


与无法在条件python中分配变量的方式非常相似,这似乎是在强制推行“最佳实践”。

作为程序员,我们都应该非常、非常、非常努力地避免使用全局变量。你正在传球给帕尔马obj,所以也许你也可以传球给球员。我将球员设置为全局球员,因为球员是一个全局对象,游戏循环的其余部分可以访问。否则我怎么申报这个项目呢。必须通过项目内的各种功能对其进行初始化和修改。如果游戏状态不应该是全球性的,那么其他什么应该是全球性的。obj传递给输入,因为它是播放器输入的一部分,因此是在函数中创建的。玩家对象代表游戏世界中的当前玩家状态。实例可以是全局的并不意味着它们必须是全局的。只需将对象传递到需要它们的函数中。
lib.py
需要从
data.py
导入
player
。如果一个模块需要了解另一个模块中的某些内容,那么是的,您必须导入它。Python的建议是什么意思?您不能在条件中分配变量?您可以,但只能从3.8版开始,因此如果使用它,您需要在3.8版中运行代码。我正在尝试为自己的rot13编码器移植到Python。但是python 2和3不允许我这么做。
class Item:
    _id=0
    desc=''
    interaction=''
    location=None
    def __init__(self,desc=desc,interact=interaction,location=location):
        self.desc=desc
        self.interaction=interact
        self.location=location
        self._id=Item._id
        Item._id+=1
    def get_item(self,player):
        move_location(self,-1)
        print("You have grabbed {} and put it into your \033[1minventory".format(self.desc))

    def move_location(self,location):
        self.location=location

class Weapon(Item):
    damage=0
    desc='It is a weapon'
    def __init__(self,damage=damage,desc=desc):
        self.damage=damage
        self.desc=desc


class World():
    rooms={}
    def __init__(self):
        pass
    def add_room(self,room):
        self.rooms[(room.x,room.y)]=room

class Mailbox(Item):
    contains='letter'
    def __init__(self,contains=contains):
        Item.__init__(self)
        self.contains=contains

class Player:
    x=0
    y=0
    location=None
    weapon=None
    dead=False
    hp=10
    def __init__(self):
        self.x=0
        self.y=0
        self.weapon=None
        self.dead=False
        self.location=None
        self.hp=10

    def damaged(amount):
        self.hp=self.hp-amount

class Inventory(Player):
    items={}
    def __init__(self,items=items):
        self.items=items

    def add(self,item):
        self.items.append(item)

    def show(self):
        for item in self.items:
            print(item._id.desc)

    def use(self,item):
        if item in items:
            print(item.interaction)
        else:
            print("You don't have that item")

class Room:
    desc="You're in a room"
    items=None
    mobs=None
    x=0
    y=0
    _id=0
    exits={}
    def __init__(self,desc=desc,items=items,mobs=mobs,x=x,y=y,exits=exits):
        self.exits=exits
        self.desc=desc
        self.items=items
        self.mobs=mobs
        self.x=x
        self.y=y
        self._id=Room._id
        Room._id+=1

    def add_moves(self,moves=exits):
        self.exits.update(moves)

    def move(self,movement,player):
        selected_move=self.exits.get(movement,None)
        if  selected_move:
            player.location=selected_move
        else:
            return None


class Mob:
    _id = 0
    desc="You can't discern anything about it."
    interact="It just looks at you."
    room=None
    alive=True
    name='None'
    hp=5
    def __init__(self,desc=desc,interact=interact,alive=alive,name=name,hp=hp):
        self.name=name
        self.desc=desc
        self.interact=interact
        self._id=Mob.id
        Mob._id+=1
        self.alive=alive
        self.hp=hp

class Grue(Mob):
    def __init__(self):
        super().__init__(desc='A giant grue stands before you',interact='You were eaten by a grue',name='Grue',hp=10)