Python 名称空间:如何根据外部类的类变量设置内部类的类变量?
我试图用python“模拟”名称空间。我正在使用内部和外部类hiraches来创建我的名称空间。例如,您希望在一个位置保存文件(如资源)的路径。我试过这样的方法:Python 名称空间:如何根据外部类的类变量设置内部类的类变量?,python,namespaces,Python,Namespaces,我试图用python“模拟”名称空间。我正在使用内部和外部类hiraches来创建我的名称空间。例如,您希望在一个位置保存文件(如资源)的路径。我试过这样的方法: src = #path to source folder class Resources: root = src + "Resources\\" class Fonts: root = Resources.root + "fonts\\" font1 = root + "font1.
src = #path to source folder
class Resources:
root = src + "Resources\\"
class Fonts:
root = Resources.root + "fonts\\"
font1 = root + "font1.ttf"
font2 = root + "font2.ttf"
class Images:
root = Resources.root + "images\\"
logo = root + "logo"
image1= root + "image1"
class StyleSheets:
root = Resources.root + "stylesheets\\"
default = root + "default.qss"
class JsonData:
root = src + "Data\\"
class TableEntries:
root = JsonData.root
entries1 = root + "Entries1.json"
entries2 = root + "Entries2.json"
logoPath = Resources.Images.image1
访问元素将如下所示:
src = #path to source folder
class Resources:
root = src + "Resources\\"
class Fonts:
root = Resources.root + "fonts\\"
font1 = root + "font1.ttf"
font2 = root + "font2.ttf"
class Images:
root = Resources.root + "images\\"
logo = root + "logo"
image1= root + "image1"
class StyleSheets:
root = Resources.root + "stylesheets\\"
default = root + "default.qss"
class JsonData:
root = src + "Data\\"
class TableEntries:
root = JsonData.root
entries1 = root + "Entries1.json"
entries2 = root + "Entries2.json"
logoPath = Resources.Images.image1
不幸的是,由于以下错误,这不起作用:
root = Resources.root + "fonts\\"
NameError: name 'Resources' is not defined
我的问题
是否可以基于外部类的类变量设置内部类的类变量?如果没有,是否有其他方法可以访问如上所示的元素而不使用多个文件
是否可以基于外部类的类变量设置内部类的类变量
如果不使用自定义元类来处理内部类,这肯定无助于可读性和可维护性(任何有经验的python程序员都会正确地将其视为一个完整的WTF)
编辑:实际上,对于您的示例代码片段,元类解决方案并没有那么复杂,请参见本答案的结尾
原因是在Python中,几乎所有事情都发生在运行时class
是一个可执行语句,类对象仅在整个class语句体结束后创建并绑定到它的名称
如果没有,是否有其他方法可以访问如上所示的元素而不使用多个文件
非常简单(简化的示例):
编辑:经过一点思考后,基于元类的用例解决方案就不会那么复杂了(但这不会是通用的):
我认为您在OOP中没有明确的类和instances的概念。如果要存储此类信息
Resources
不应该是类,它应该是Dir
类的实例
class Dir:
def __init__(self, path="/", parent=None):
self.parent = parent
self.path = path
self.contents = {}
def __getitem__(self, key):
return self.contents[key]
def create_subdir(name):
self.contents[name] = Dir(os.path.join(self.path + name), self)
def add_file(file):
self.contents[file] = file # You should probably also have a File type
# ...
resources = Dir(os.path.join(src, "Resources"))
resources.create_subdir("fonts")
fonts = resources["fonts"]
fonts.add_file("font1.ttf")
...
我使用了os.path.join
函数来委托Python为每个SO选择正确的分隔符,而不是像您这样硬编码Windows分隔符。\uuuu getitem\uuuu
方法允许像直接获取字典一样获取项目
编辑:
如果您不喜欢pathlib的格式,可以利用标准模块并添加属性访问符号(使用“.”来访问子目录)
from pathlib import Path as Path_, WindowsPath as WPath_, PosixPath as PPath_
import os
class Path(Path_):
def __new__(cls, *args, **kwargs):
return super().__new__(WindowsPath if os.name == 'nt' else PosixPath,
*args, **kwargs)
def __getattr__(self, item):
if item == '_str':
raise AttributeError
for i in self.iterdir():
if i.name == item:
return i
raise AttributeError
class WindowsPath(WPath_, Path):
pass
class PosixPath(PPath_, Path):
pass
current = Path()
subdir = current.subdir_name # current / 'subdir_name'
我们为什么不使用字典呢?在
Resources
类定义之外,定义完成后,Resources.Fonts.root=Resources.root+“Fonts\\”
将起作用,但为什么要这样做呢?python中的名称空间是通过使用子模块模拟的,不使用内部类。@Stephernauch您能举一个例子说明您使用字典的解决方案吗?是的,在类外设置变量是可行的,但是我必须声明Resources.Fonts.font1=Resources.Fonts.root+“font1.tff”
,这看起来很奇怪。我想要干净的结构化代码。在我看来,访问上述资源可以提高可读性和可更改性。@Adirio这意味着我必须创建多个文件,对吗?我想故意避免这种情况。你应该看看标准库。这是使用路径进行操作的python方法。尽量避免使用str(pathlib.Path())
。相反,请按照中的建议使用os.fspath(pathlib.Path())
。我认为OP实际上很清楚类和实例是什么,正如前面所述,这里的目的是将类仅仅用作对象来“模拟名称空间”(请记住,在Python中,类也是对象)@Truntle编辑了我的答案,其中包括了一个如何将这种符号添加到python标准库的示例。遗憾的是,这并不像我希望的那么简单,但也不是很复杂(至少是第一个解决方案)。