【问题标题】:Organize objects using un-instantiated classes as namespaces?使用未实例化的类作为命名空间来组织对象?
【发布时间】:2019-11-02 13:42:35
【问题描述】:

我已经构建了一个模块来保存所有常见的 selenium expected_conditions,然后在各种测试中引用它们。 (这个例子的硒部分并不重要,只是我有一个包含几千个项目的“目录”。)

# ec module
class EcHR(object):
    class sidemenu(object):
        hrfile: Clickable      = Clickable((By.ID, "sidemenu_HRFile"),       f"HR File")
        hrvistainfo: Clickable = Clickable((By.ID, "sidemenu_HRVistA Info"), f"HR VistA Info")
    class hrfile(__hr_search__):
        class actionmenu(__hr_search__.actionmenu):
            add: Clickable       = Clickable((By.ID, "NewHireLink"), f"Add {BUTTON}")
            personnel: Clickable = Clickable((By.ID, 'setEmpType'), f"Personnel Filter {DROPDOWN}")
            status: Clickable    = Clickable((By.ID, 'setStatus'), f"Status {DROPDOWN}")
            configure: Clickable = Clickable((By.ID, "configureLinkGen"), f"Configure {BUTTON}")
            reports: Clickable   = Clickable((By.ID, 'Reports'), f"Reports {BUTTON}")
            class addmenu(object):
                employee: Clickable = Clickable((By.ID, f'Employee'), f"Add->Employee {BUTTON}")

对 ec 模块中给定项目的示例引用。

import ec

    # navigation helper method for a given page
    def do_hrfile_nav(self):
        self.clickbutton(ec.EcHR.sidemenu.hrfile)

这很好用;我可以跟踪每个对象的使用情况,同时仍然提供对象是什么的可读性上下文。

self.clickbutton(ec.EcHR.sidemenu.hrfile) 告诉读者我们正在点击HR 页面上的侧面菜单项hrfile。这对于区分 ec.EcHR.hrfile 很重要,ec.EcHR.hrfile 是一组不同的对象。

我的问题:有没有更好/更简洁的方式来组织这些对象?我正在使用永远不会被实例化的类。 (由于我无法表达的原因,不知何故感觉很尴尬)这些类仅作为一种以有组织的方式引用它们的手段。也许某种具有类结构的轻量级数据对象? (我是不是想太多了?)

【问题讨论】:

  • 重复 -- here -- 赏金结束后我将关闭。德普。 (不知道为什么我第一次写这个问题时没有出现其他问题)
  • 我看到链接的答案分为做和不做(改用模块)。这对于可读性来说是完美的,不会污染命名空间,因为建立了一个包含的名称层次结构,并且比创建模块文件树要简单得多。
  • 别扭的感觉只是因为很少见。与此相关的是,您可能有枚举、命名元组和数据类。
  • @progmatico 我认为你是对的。

标签: python namespaces


【解决方案1】:

我有一些想法。 可能有用。

将函数用作命名空间怎么样?

@namespace
def EcHR():
    @namespace
    def sidemenu():
        hrfile: Clickable = Clickable((By.ID, "sidemenu_HRFile"), f"HR File")
        return locals()

    @namespace
    def hrfile():
        @namespace
        def actionmenu():
            add: Clickable = Clickable((By.ID, "NewHireLink"), "Add {BUTTON}")

            @namespace
            def addmenu():
                employee: Clickable = Clickable(
                    (By.ID, f"Employee"), "Add->Employee {BUTTON}"
                )
                return locals()

            return locals()

        return locals()

    return locals()

我已将每个 class 更改为一个函数。并且每个函数都必须使用 namespace 装饰器进行装饰,并且必须返回 locals() 或任何带有自定义键、val 映射的 dict

这是NameSpace 类和namespace 装饰器。

from functools import reduce

class NameSpace:
    def __init__(self, name):
        self.__name__ = name

    def __str__(self):
        return "{}".format(self.__name__)

    def __repr__(self):
        return "NameSpace({})".format(self.__name__)

    def __call__(self):
        pass

def namespace(func):
    return reduce(
        lambda ns, kv: setattr(ns, kv[0], kv[1]) or ns,
        func().items(),
        NameSpace(func.__name__),
    )

namespace 装饰器运行装饰函数并将返回的dict 转换为NameSpace 实例。

如何访问对象?

print(EcHR.sidemenu.hrfile)
print(EcHR.hrfile.actionmenu.addmenu.employee)

【讨论】:

  • 这真的很有趣。我将不得不玩它。从表面上看,当简单地使用未实例化的类时,它似乎提供了与我免费获得的相同的东西。也就是说,从可读性的角度来看,很明显这些是“命名空间”。所以也许这是值得的。
  • 终于又好又好用的改进了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2019-03-12
  • 1970-01-01
相关资源
最近更新 更多