假设我有一些正在处理的RPG函数......
def name_of_function():
action
并希望在每个函数中实现ax类(见下文),而不必重写每个类。我如何将该类创建为全局类。我不确定我是否使用了正确的术语,但请帮忙。这一直让我难以创建基于文本的RPG游戏。全局类的一个例子很棒!
class axe:
attack = 5
weight = 6
description = "A lightweight battle axe."
level_required = 1
price = 10
答案 0 :(得分:7)
你无法在Python中创建任何真正全局的东西 - 也就是说,无论如何,任何模块都可以神奇地使用它。但是一旦你理解了模块和导入工作的方式,这几乎不重要。
通常,您可以创建类并将它们组织到模块中。然后将它们导入到需要它们的任何模块中,这会将类添加到模块的符号表中。
因此,例如,您可以创建一个名为weapons.py
的模块,并在其中创建一个WeaponBase
类,然后从{{1}派生Axe
和Broadsword
个类}}。然后,在需要使用武器的任何模块中,你都要放
WeaponsBase
位于文件顶部。执行此操作后,import weapons
会返回weapons.Axe
类,Axe
会返回weapons.Broadsword
类,依此类推。你也可以使用:
Broadsword
将from weapons import Axe, Broadsword
和Axe
添加到模块的符号表中,允许代码完全按照您的要求执行操作。
您也可以使用
Broadsword
但由于两个原因,这通常不是一个好主意。首先,它会导入模块中的所有内容,无论您是否要使用它 - 例如from weapons import *
。其次,如果WeaponsBase
中的某个函数与导入模块中的函数同名,则会遇到各种令人困惑的问题。
weapons
系统中存在许多细微之处。例如,您必须小心确保模块不会尝试相互导入。最终,您的项目变得足够大,以至于您不希望将所有模块放在同一目录中,并且您必须了解import
之类的内容。但你可以担心这一点。
答案 1 :(得分:2)
我不同意见,你不能在python中创建真正全局的东西。事实上,这很容易。在Python 3.1中,它看起来像这样:
def get_builtins():
"""Due to the way Python works, ``__builtins__`` can strangely be either a module or a dictionary,
depending on whether the file is executed directly or as an import. I couldn’t care less about this
detail, so here is a method that simply returns the namespace as a dictionary."""
return getattr( __builtins__, '__dict__', __builtins__ )
就像其他一些东西一样,内置函数是Py3在细节上与Py2中的工作方式不同的一点。有关详细信息,请阅读python.org上的“Python X.X中的新功能”文档。我不知道上述公约的原因是什么;我只是想忽略那些东西。我认为上面的代码也应该在Py2中工作。
所以关键是这里有一个__builtins__
东西,其中包含许多内容,因为内置于Python中。您已经爱上的所有sum
,max
,range
内容。好吧,差不多一切。但你真的不需要细节。你能做的最简单的事就是说
G = get_builtins()
G[ 'G' ] = G
G[ 'axe' ] = axe
代码中始终保证执行的位置。 G
代表全局可用的命名空间,因为我在G
内注册了G
,G
现在神奇地超越了它存在于每个模块的背景中。意味着你应该小心使用它。如果命名冲突发生在G
和模块命名空间中的任何内容之间,则模块的命名空间应该获胜(因为它首先被检查)。此外,当你告诉他们你正在污染全球的NAMESPACE犯罪时,请准备好让每个人都跳过你。我很惊讶,至今还没有人对此进行过共处。
import
语句完成一些不那么微不足道的事情时,绝望就会降临。这些天,我只使用import
作为标准库和定期安装的模块;对于我自己的东西,我使用自己开发的系统。我能说什么,它有效!
啊是的,还有两点:如果你喜欢这个解决方案,请自己帮个忙,给自己写一个监督你的publish()
方法之类的方法永远不会发布已经被采用过的名字。在大多数情况下,你不希望这样。
最后,让我第二个第一个评论者:我一直按照你在上面展示的风格进行编程,因为你在教科书的例子中找到了(大部分时间使用car
s,而不是{{1}确定)。出于相当多的原因,我几乎已经放弃了。
考虑这一点:JSON定义了七种数据:null,true,false,数字,文本,列表,字典,就是这样。我声称你可以使用那些建模任何其他有用的数据类型。
对于诸如套装,行李,有序词典等等,还有很多理由。这里的主张并不是说回归纯粹的JSON兼容表格总是方便或恰当的;声称只是可以模拟。现在,我正在实现一个稀疏列表用于消息传递系统, 数据类型i 做在经典OOP中实现。这就是它的好处。
但我永远不会定义超出这些通用数据类型的类。相反,我编写的库采用通用数据类型并提供您需要的功能。我的所有业务数据(在您的情况下可能代表玩家,场景,工具等)都会进入通用数据容器(通常是axe
s)。我知道这种架构方式存在开放性问题,但编程变得越来越容易,因为我通过BS打破了OOP宣传的一部分(除了真正有用和美好的东西,另一部分) OOP是)。
哦,是的,我提到过,只要您将业务数据保存在JSON兼容对象中,您就可以随时将它们写入磁盘并从磁盘中复活它们吗?或通过电线发送它们,以便您可以与远程玩家互动?如果你想这样做,那么序列化业务在古典OOP中会变得多么令人难以置信的扭曲(阅读this了解冰山一角)?在这个领域你必须知道的大多数技术细节对你的余生都毫无意义。
答案 2 :(得分:2)
您可以通过执行以下任一操作来添加(或更改现有的)Python内置函数和类,至少在Py 2.x中。之后,默认情况下,您添加的任何内容都可用于所有代码,但不是永久性的。
免责声明:由于可能存在名称冲突而导致此类事情可能会造成危险,并且因为它非常非显式而存在问题。但是,嘿,正如他们所说,我们都是成年人,对吗?
class MyCLass: pass
# one way
setattr(__builtins__, 'MyCLass', MyCLass)
# another way
import __builtin__
__builtin__.MyCLass = MyCLass
答案 3 :(得分:1)
另一种方法是创建一个单身人士:
class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls.instance = None
class GlobalClass(object):
__metaclass__ = Singleton
def __init__():
pinrt("I am global and whenever attributes are added in one instance, any other instance will be affected as well.")