Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 名称空间:如何根据外部类的类变量设置内部类的类变量?_Python_Namespaces - Fatal编程技术网

Python 名称空间:如何根据外部类的类变量设置内部类的类变量?

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.

我试图用python“模拟”名称空间。我正在使用内部和外部类hiraches来创建我的名称空间。例如,您希望在一个位置保存文件(如资源)的路径。我试过这样的方法:

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标准库的示例。遗憾的是,这并不像我希望的那么简单,但也不是很复杂(至少是第一个解决方案)。