多类对象“链接”?

时间:2019-12-23 09:15:20

标签: python vba class

我是Python的新手,并且具有VBA的从业经验。 我希望用Python创建类,以便可以实现以下语法:

Company('MS').Department('Finance').Employee('John').FullName = 'John MacDonalds'
Company('MS').Department('Finance').Employee('John').Wages = '5000'

我开始意识到,在Python中声明Class结构与VBA完全不同。

我采用正确的方法吗?如果没有,对于此父/子结构,是否还有其他建议的方法?

2 个答案:

答案 0 :(得分:0)

我真的认为继承不是很好的用途。良好的继承是指可以轻松地将子类替换为父类的情况。员工可以代替部门吗?那似乎不对。部门不能做员工不能做的很多事情吗?对于员工无法执行的部门所具有的每个职能,您必须在子类中拥有一个“未实施新功能”。

这被称为Liskov替代原理。基本上,子类必须可以替代其基类。我最喜欢的例子是鸟类和企鹅。您可以设置一个鸟类,并从该类中继承许多不同种类的鸟。但是,当您创建一个继承自bird的企鹅类时会发生什么?企鹅不会飞,但是鸟类会飞。因此,在penguin类中,您将实现此功能,并且不得不说“抛出未实现的新东西”。这不是很好,因为如果您将企鹅放在某个功能会出现鸟类的地方,当您给它戴企鹅时,它将发疯并崩溃。

我希望能有所帮助。我对Python不太熟悉,但是我了解继承。

答案 1 :(得分:0)

您还没有真正说出您想要完成的语法,这将有助于您了解...

如下所示的嵌套类将使您能够实现所需的语法,但结果不仅非常“不合逻辑”,而且完全没有用,我想不出一种合理的方式来实现这一点。

在没有关于您正在做的事情的更多信息的情况下,目前我可以考虑提出另一种建议。我建议您只创建一堆常规的非嵌套类,并在需要时显式实例化它们。

请注意,我已经更改了您在PEP 8 naming conventions之后的名字。

class Company:
    def __init__(self, name):
        self.name = name

    class Department:
        def __init__(self, dept_name):
            self.dept_name = dept_name

        class Employee:
            def __init__(self, given_name):
                self.given_name = given_name


Company('MS').Department('Finance').Employee('John').full_name = 'John MacDonalds'

这是一种使用此answer中定义的Vividict字典通过Python“ autovivification”实现树结构的方法。

我已经对其进行了调整,以在层次结构的每个级别上支持不同的Vividict 子类:即CompanyDepartmentEmployee 。每个子类都定义了一个名为subtype的类属性,Vividict基类的__missing__()将在创建缺少的键值时使用。我还为每个实例添加了__repr__()方法,以使实例打印出它们包含的所有项目。

这只是一个概念证明,我真的不知道您是否可以使用它,但是它应该使您对使用某种可读性强的语法来完成所需工作的一种方式有所了解。< / p>

class Vividict(dict):  # Base class.
    subtype = dict
    def __missing__(self, key):
        value = self[key] = self.subtype(key)
        return value

class Employee:  # Leaf - Regular class
    def __init__(self, given_name):
        self.given_name = given_name
    def __repr__(self):
        return f'{self.__class__.__name__}({self.given_name!r})'

class Department(Vividict):  # Branch.
    subtype = Employee
    def __init__(self, dept_name):
        self.dept_name = dept_name
    def __repr__(self):
        return (f'{self.__class__.__name__}({self.dept_name!r})' + '\n    '
                + repr(list(self.values())))

class Company(Vividict):  # Root of tree.
    subtype = Department
    def __init__(self, co_name):
        self.co_name = co_name
    def __repr__(self):
        return (f'{self.__class__.__name__}({self.co_name!r})' + '\n  '
                + repr(list(self.values())))

company = Company('MS')
company['Finance']['George'].full_name = 'George Brown'
company['Finance']['Mary'].full_name = 'Mary Jones'
print(company)

输出:

Company('MS')
  [Department('Finance')
    [Employee('George'), Employee('Mary')]]