Python3中类内的名称空间
我是Python新手,我想知道是否有办法将方法聚合到“子空间”中。我的意思类似于这种语法:Python3中类内的名称空间,python,python-3.x,class,namespaces,Python,Python 3.x,Class,Namespaces,我是Python新手,我想知道是否有办法将方法聚合到“子空间”中。我的意思类似于这种语法: smth = Something() smth.subspace.do_smth() smth.another_subspace.do_smth_else() 我正在编写一个API包装器,我将有很多非常相似的方法(只是不同的URI),所以我认为最好将它们放在几个引用API请求类别的子空间中。换句话说,我想在类中创建名称空间。我不知道这在Python中是否可行,我知道在Google中应该寻找什么 我将非常
smth = Something()
smth.subspace.do_smth()
smth.another_subspace.do_smth_else()
我正在编写一个API包装器,我将有很多非常相似的方法(只是不同的URI),所以我认为最好将它们放在几个引用API请求类别的子空间中。换句话说,我想在类中创建名称空间。我不知道这在Python中是否可行,我知道在Google中应该寻找什么
我将非常感谢您的帮助。一种方法是将
子空间
和另一个子空间
定义为属性,分别返回提供do\u smth
和do\u smth\u else
的对象:
class Something:
@property
def subspace(self):
class SubSpaceClass:
def do_smth(other_self):
print('do_smth')
return SubSpaceClass()
@property
def another_subspace(self):
class AnotherSubSpaceClass:
def do_smth_else(other_self):
print('do_smth_else')
return AnotherSubSpaceClass()
这正是您想要的:
>>> smth = Something()
>>> smth.subspace.do_smth()
do_smth
>>> smth.another_subspace.do_smth_else()
do_smth_else
根据您打算使用这些方法的目的,您可能希望将
子空间类
设置为单例,但我怀疑这样做是否值得。几年前我就有这个需要,并提出了以下建议:
类注册表:
“”“类中的命名空间。”“”
定义获取(自、对象、cls=None):
如果obj为无:
回归自我
其他:
返回InstanceRegistry(self,obj)
定义调用(self,name=None):
def装饰器(f):
使用名称=名称或f.。\u名称__
如果hasattr(self,使用_名称):
raise VALUERROR(“%s已注册”%use\u name)
setattr(self、name或f._name、f)
返回f
返回装饰器
类实例注册表:
"""
用于从类的实例访问命名空间的帮助器。
内部使用人:class:`Registry`。返回将通过
实例作为第一个参数。
"""
定义初始化(自、注册表、obj):
self.\uuu注册表=注册表
自。u_obj=obj
def _ugetattr _;(self,attr):
返回部分(getattr(self.\u注册表,attr),self.\u obj)
#用法:
分类:
子空间=注册表()
另一个子空间=注册表()
@MyClass.子空间()
def do_smth(自身):
#‘self’将是一个例子
通过
@MyClass。另一个子空间('do_smth_else'))
定义此参数可以被称为任意参数名称(obj,其他):
#如果课堂外的“self”让人不安,可以叫它“obj”或其他任何东西
通过
在运行时:
smth=Something()
>>>子空间do_smth()
>>>smth。另一个子空间。dosmth_else('other'))
这与Py2和Py3兼容。在Py3中可以进行一些性能优化,因为
\uuuu set\u name\uuuu
告诉我们名称空间的调用方式,并允许缓存实例注册表。这些是否确实需要是方法?他们需要进入任何州吗?您可以只使用嵌套模块吗?像这样的方法是否需要像常规方法一样访问实例?我将登录信息存储为实例的属性。我需要通过各种方法访问它们。也许有更好的方法来储存它们。有趣的概念。我想你可以通过在\uuuu init\uuu
方法中执行self.subspace=self.other\u subspace=self
来伪造它。当然,这并不是创建单独的名称空间,尽管它允许您描述的调用语法。OTOH,它不会阻止人们做smth.do\u smth()
。不会做的事情(owner=self…
,有点实现了这一点?子类可以从其所有者那里查找他们需要的任何信息,您的名称空间将符合您的意图。子类将有一个do\smth
方法。这是一个非常优雅的解决方案,可以按预期工作。谢谢。这很有效,但每次您访问smth.subspace
或sm时另一个子空间
创建了一个新的内部类对象。通过在方法中打印
other\u self,您可以看到这一点。哦,我想这并不比实例方法通常在每次调用时都被重新绑定的事实更糟糕。但是如果这些内部类包含很多方法,那么每次重新构建它们都会减慢速度。@mDevv:我不同意。正如PM所指出的,这每次都会创建一个新的类对象。至少要将这些类移出方法。接下来,你还必须担心共享状态。我会考虑重构你的API,使其不需要名称空间?如前所述,如果性能是一个问题,你可以使它们成为单例,但对于大多数应用程序来说,这确实是个问题不应该。当解决方案涉及新的类实例化时,我相信它会增加不必要的复杂性