python中的组合和聚合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19861785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:49:39  来源:igfitidea点击:

composition and aggregation in python

python

提问by Katsu

I want to know how to implement composition and aggregation in UML termsin python.

我想知道如何在python中以UML术语实现组合和聚合。

If I understood:

如果我理解:

  1. Aggregation:
  1. 聚合:

class B:
    pass

class A(object):
    def __init__(self):
        self.B = B

  1. Composition:
  1. 作品:

In other languages I saw this implemented as a pointer to B. I guess here self.Bis a pointer in python.

在其他语言中,我看到这是作为指向 B 的指针实现的。我猜这self.B是 python 中的一个指针。

class A(object):
    def __init__(self, B):
        self.B = B

Is it right?

这样对吗?

采纳答案by Hannele

If I understand correctly, aggregation vs composition is about the responsibilities of an object to its members (e.g. if you delete an instance, do you also delete its members?).

如果我理解正确,聚合与组合是关于对象对其成员的责任(例如,如果您删除一个实例,您是否也删除了它的成员?)。

Mainly, it will depend a lot on the implementation. For example, to create a class A which receives an instance of class B (aggregation), you could write the following:

主要是,它将在很大程度上取决于实施。例如,要创建一个接收类 B(聚合)的实例的类 A,您可以编写以下内容:

class B(object): pass

class A(object):
    def __init__(self, b):
        self.b = b

b = B()
a = A(b)

But as a point of caution, there is nothing built-in to Python that will prevent you from passing in something else, for example:

但需要注意的是,Python 没有内置任何内容可以阻止您传入其他内容,例如:

a = A("string") # still valid


If you would like to create the instance of B inside the constructor of A (composition), you could write the following:

如果您想在 A(组合)的构造函数中创建 B 的实例,您可以编写以下内容:

class A(object):
    def __init__(self):
        self.b = B()

Or, you could inject the class into the constructor, and then create an instance, like so:

或者,您可以将类注入构造函数,然后创建一个实例,如下所示:

class A(object):
    def __init__(self, B):
        self.b = B()


As an aside, in at least your first example and possibly the second, you are setting B to the class definition of B, not to an instance of it:

顺便说一句,至少在您的第一个示例和可能的第二个示例中,您将 B 设置为 B 的类定义,而不是它的实例:

class A(object):
    def __init__(self, B):
        self.B = B

>>> a = A()
>>> a.B # class definition
<class __main__.B at 0x028586C0>
>>> a.B() # which you can make instances of
<__main__.B instance at 0x02860990>

So, you end up with an instance of A pointing to the class definition of B, which I'm fairly sure is not what you're after. Although, that is generally much harder to do in other languages, so I understand if that was one of the points of confusion.

所以,你最终得到一个 A 的实例,指向 B 的类定义,我很确定这不是你想要的。虽然,这在其他语言中通常要困难得多,所以我理解这是否是混淆点之一。

回答by N Randhawa

Composition and aggregation are specialised form of Association. Whereas Association is a relationship between two classes without any rules.

组合和聚合是关联的特殊形式。而关联是两个类之间没有任何规则的关系。

Composition

作品

In composition, one of the classes is composed of one or more instance of other classes. In other words, one class is container and other class is content and if you delete the container object then all of its contents objects are also deleted.

在组合中,一个类由其他类的一个或多个实例组成。换句话说,一个类是容器,另一个类是内容,如果删除容器对象,那么它的所有内容对象也将被删除。

Now let's see an example of composition in Python 3.5. Class Employeeis container and class Salaryis content.

现在让我们看看 Python 3.5 中的组合示例。类Employee是容器,类Salary是内容。

class Salary:
    def __init__(self,pay):
        self.pay=pay

    def get_total(self):
       return (self.pay*12)

class Employee:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus
        self.obj_salary=Salary(self.pay)

    def annual_salary(self):
        return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)


obj_emp=Employee(100,10)
print (obj_emp.annual_salary())

Aggregation

聚合

Aggregation is a weak form of composition. If you delete the container object contents objects can live without container object.

聚合是组合的一种弱形式。如果删除容器对象的内容,对象可以在没有容器对象的情况下存活。

Now let's see an example of aggregation in Python 3.5. Again Class Employeeis container and class Salaryis content.

现在让我们看看 Python 3.5 中的聚合示例。同样,类Employee是容器,类Salary是内容。

class Salary:
    def __init__(self,pay):
        self.pay=pay

    def get_total(self):
       return (self.pay*12)

class Employee:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus

    def annual_salary(self):
        return "Total: "  +  str(self.pay.get_total()+self.bonus)


obj_sal=Salary(100)
obj_emp=Employee(obj_sal,10)
print (obj_emp.annual_salary())

回答by macm

# Aggregation is NOT exclusive
class BaseChapter:
    '''
    We can use this BaseChapter in any book, like in OpenBook.
    '''

    def __init__(self, name):
        self.name = name
        self.subject = None
        self.content = None
        return

class OpenBook:

    def __init__(self, isbn):
        self.isbn = isbn
        self.chapters = list()

    def add_chapter(self, obj):

        # This constrain dont have correlation with composition/aggregation
        if isinstance(obj, BaseChapter):
            self.chapters.append(obj)
        else:
            raise TypeError('ChapterError')

# .. but Composition is Exclusive
# Example:
class MyBook:

    class MyChapter:
        '''
        This MyChapter can be used only by MyBook
        '''
        def __init__(self, name, subject):
            self.name = name
            self.subject = subject
            self.title = None
            self.content = None
            self.techincal_refs = list()
            return

    def __init__(self, isbn):
        self.isbn = isbn
        self.chapters = list()

    def add_chapter(self, obj):
        # This constrain dont have correlation with composition/aggregation
        # what is important here is MyChapter can be used only by MyBook
        # a outside object cant create a instance of MyChapter
        if isinstance(obj, self.MyChapter):
            self.chapters.append(obj)
        else:
            raise TypeError('ChapterError')

.. and yes we can do better like

.. 是的,我们可以做得更好

class MyBook:

    class MyChapter(BaseChapter):
        '''
        This MyChapter can be used only by MyBook,
        but now is based in BaseChapter.
        But you knhow, python dont create problems if you still want
        create a instance of MyChapter in other 'Books'.

        But when you see this code you will think, This class is exclusive
        to MyBook.
        '''
        def __init__(self, name):
            super().__init__(name)
            self.subject = None
            self.title = None
            self.content = None
            self.techincal_refs = list()
            return

    def __init__(self, nib):
        self.nib = nib
        self.chapters = list()

    def add_chapter(self, obj):
        # This constrain dont have correlation with composition/agregation
        # what is important here is MyChapter can be used only by MyBook
        if isinstance(obj, self.MyChapter):
            self.chapters.append(obj)
        else:
            raise TypeError('ChapterError')