{"id":4953,"date":"2015-06-08T18:45:20","date_gmt":"2015-06-08T15:45:20","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=4953"},"modified":"2015-06-08T18:32:49","modified_gmt":"2015-06-08T15:32:49","slug":"python-decorator-simplifying-delegate-pattern","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/","title":{"rendered":"Python Decorator for Simplifying Delegate Pattern"},"content":{"rendered":"<p>Recently, I posted about <a href=\"https:\/\/programmingideaswithjake.wordpress.com\/2015\/05\/09\/replacing-inheritance-with-composition\/\">how you can use composition instead of inheritance<\/a>, and in that article, I mentioned the Delegate Pattern. As a quick description, the pattern has you inherit from the parent interface (or, in Python, you can just implement the protocol), but all the methods either redirect to calling the method on an injected implementation of interface\/protocol, possibly surrounding the call in its own code, or it completely fills the method with its own implementation.<\/p>\n<p>For the most part, it is like manually implementing inheritance, except that the superclass in injectable.<\/p>\n<p>Anyway, one of the more annoying parts of implementing the Delegate Pattern is having to write all of the delegated calls. So I decided to look into the possibility of of making a decorator that will do that for you for all the methods you don\u2019t explicitly implement.<\/p>\n<h2><b>Standard Attribute Delegation<\/b><\/h2>\n<p>First, we need a standard way of delegating an attribute to a delegate object\u2019s attribute. We\u2019ll use a descriptor for this. Its constructor takes in the name of the delegate stored on the object as well as the name of the attribute to look up. Here\u2019s the descriptor:<\/p>\n<pre class=\" brush:php\">class DelegatedAttribute:\r\n    def __init__(self, delegate_name, attr_name):\r\n        self.attr_name = attr_name\r\n        self.delegate_name = delegate_name\r\n\r\n    def __get__(self, instance, owner):\r\n        if instance is None:\r\n            return self\r\n        else:\r\n            # return instance.delegate.attr\r\n            return getattr(getattr(instance, self.delegate_name),  self.attr_name)\r\n\r\n    def __set__(self, instance, value):\r\n        # instance.delegate.attr = value\r\n        setattr(getattr(instance, self.delegate_name), self.attr_name, value)\r\n\r\n    def __delete__(self, instance):\r\n        delattr(getattr(instance, self.delegate_name), self.attr_name)\r\n\r\n    def __str__(self):\r\n        return \"&lt;delegated attribute, '\" + self.attr_name + \"' at \" + str(id(self)) + '&gt;'<\/pre>\n<p>I added a nice <code>__str__<\/code> method to make it look a little less like a boring object and more like a feature when people do some REPL diving. Normally, I don\u2019t bother implementing the <code>__delete__<\/code> method, but I felt it was appropriate here. I doubt it\u2019ll ever be used, but if someone wants to use <code>del<\/code> on an attribute, I want it to be effective.<\/p>\n<p>Hmm, all those main methods have a repetitive part for getting the delegate object. Let\u2019s extract a method and hopefully make them a little bit more legible; nested <code>getattr<\/code>s, <code>setattr<\/code>s, and <code>delattr<\/code>s aren\u2019t the easiest thing to look at.<\/p>\n<pre class=\" brush:php\">class DelegatedAttribute:\r\n    def __init__(self, delegate_name, attr_name):\r\n        self.attr_name = attr_name\r\n        self.delegate_name = delegate_name\r\n\r\n    def __get__(self, instance, owner):\r\n        if instance is None:\r\n            return self\r\n        else:\r\n            # return instance.delegate.attr\r\n            return getattr(self.delegate(instance),  self.attr_name)\r\n\r\n    def __set__(self, instance, value):\r\n        # instance.delegate.attr = value\r\n        setattr(self.delegate(instance), self.attr_name, value)\r\n\r\n    def __delete__(self, instance):\r\n        delattr(self.delegate(instance), self.attr_name)\r\n\r\n    def delegate(self, instance):\r\n        return getattr(instance, self.delegate_name)\r\n\r\n    def __str__(self):\r\n        return \"&lt;delegated attribute, '\" + self.attr_name + \"' at \" + str(id(self)) + '&gt;'<\/pre>\n<p>There, that\u2019s a little easier to read. At the very least, we\u2019ve removed some repetition. I wish we didn\u2019t need the <code>self<\/code> reference to call it, as that would make it even easier to look at, but trying to get around it would likely be a lot of work, just as ugly, or both.<\/p>\n<p>Let\u2019s see an example of this in action:<\/p>\n<pre class=\" brush:php\">class Foo:\r\n    def __init__(self):\r\n        self.bar = 'bar in foo'\r\n    def baz(self):\r\n        return 'baz in foo'\r\n\r\nclass Baz:\r\n    def __init__(self):\r\n        self.foo = Foo()\r\n    bar = DelegatedAttribute('foo', 'bar')\r\n    baz = DelegatedAttribute('foo', 'baz')\r\n\r\nx = Baz()\r\nprint(x.bar)  # prints 'bar in foo'\r\nprint(x.baz())  # prints 'baz in foo'<\/pre>\n<p>It\u2019s as simple as making sure you have an object to delegate to and adding a <code>DelegatedAttribute<\/code> with the name of that object and the attribute to delegate to. As you can see, it properly delegates both functions and object fields as we would want. It\u2019s not only useful for the Delegate pattern but really any situation in composition where a wrapper call simply delegates the call to the wrapped object.<\/p>\n<p>This is good, but we don\u2019t want to do this by hand. Plus, I mentioned a decorator. Where\u2019s that? Hold your horses; I\u2019m getting there.<\/p>\n<h2><b>Starting the Decorator<\/b><\/h2>\n<p>See? Now we\u2019ve moved to the decorator. What is the decorator supposed to do? How should it work? First thing you should know is that we created the <code>DelegatedAttribute<\/code> class for a reason. We\u2019ll utilize that, assigning all the class attributes of the delegate object to the new class.<\/p>\n<p>To do that, we\u2019ll need a reference to the class. We\u2019ll also need to know the name of the delegate object, so it can be given to the <code>DelegatedAttribute<\/code> constructor. For now, we\u2019ll hard code that. From this, we know that we need a parameterized decorator, whose outermost signature looks like <code>delegate_as(delegate_cls)<\/code>. Let\u2019s get it started.<\/p>\n<pre class=\" brush:php\">def delegate_as(delegate_cls):\r\n    # gather the attributes of the delegate class to add to the decorated class\r\n    attributes = delegate_cls.__dict__.keys()\r\n\r\n    def inner(cls):\r\n        # create property for storing the delegate\r\n        setattr(cls, 'delegate', SimpleProperty())\r\n        # set all the attributes\r\n        for attr in attributes:\r\n            setattr(cls, attr, DelegatedAttribute('delegate', attr))\r\n        return cls\r\n  \r\n    return inner<\/pre>\n<p>You may have noticed the creation of something called a <code>SimpleProperty<\/code>, which won\u2019t be shown. It is simply a descriptor that holds and returns a value given to it, the most basic of properties.<\/p>\n<p>The first thing it does is collect all the attributes from the given class so it knows what to add to the decorated class, preparing it for the inner function that does the real work. The inner function is the real decorator, and it takes that sequence and adds those prepared attributes to the decorated class using <code>DelegatedAttribute<\/code>s.<\/p>\n<p>This may all seem alright, but it doesn\u2019t actually work. The problem is that some of those attributes that we try to add on to the decorated class are ones that come with every class and are read only.<\/p>\n<h2><b>Skipping Some Attributes<\/b><\/h2>\n<p>So we need to skip over some attributes in the list. I had originally done this by creating a \u201cblacklist\u201d set of attribute names that come standard with every class. But then I realized that implementing a different requirement of the decorator would take care of it already. That requirement is that the decorator not write over any of the attributes that the class had explicitly implemented.<\/p>\n<p>So, if the decorated class defines its own version of a method that the delegate has, the decorator should not add that method. Ignoring those attributes works the same as ignoring the ones I would put into the blacklist, since they\u2019re already defined on the class.<\/p>\n<p>So here\u2019s what the code looks like with that requirement added in.<\/p>\n<pre class=\" brush:php\">def delegate_as(delegate_cls):\r\n    # gather the attributes of the delegate class to add to the decorated class\r\n    attributes = set(delegate_cls.__dict__.keys())\r\n\r\n    def inner(cls):\r\n        # create property for storing the delegate\r\n        setattr(cls, 'delegate', SimpleProperty())\r\n        # don't bother adding attributes that the class already has\r\n        attrs = attributes - set(cls.__dict__.keys())\r\n        # set all the attributes\r\n        for attr in attrs:\r\n            setattr(cls, attr, DelegatedAttribute('delegate', attr))\r\n        return cls\r\n  \r\n    return inner<\/pre>\n<p>As you can see, I turned the original collection of keys into a <code>set<\/code> and did the same with the attributes from <code>cls<\/code>. This is because we want to remove one set of keys from the other, and a really simple way to do that is with <code>set<\/code>\u2018s subtraction. It could be done with <code>filter<\/code> or or similar, but I like the cleanliness of this. It\u2019s short, and its meaning is quite clear. I had to store the final result in <code>attrs<\/code> instead of <code>attributes<\/code> because the outer call could be reused, so we don\u2019t want to change <code>attributes<\/code> for those cases.<\/p>\n<h2><b>Some More Parameters<\/b><\/h2>\n<p>Okay, so we\u2019re now able to automatically delegate any class-level attributes from a base implementation to the decorated class, but that\u2019s often not the only public attributes that an object of a class has. We need a way to include those attributes. We could get an instance of the class and copy all the attributes that are preceded by a single underscore, or we could have the user supply the list of attributes wanted. I personally prefer to take in a user-supplied list. So, we\u2019ll add an additional parameter to the decorator called <code>include<\/code>, which takes in a sequence of strings that are the names of attributes to delegate to.<\/p>\n<p>Next, what if there are some attributes that will be automatically copied over that we don\u2019t actually want? We\u2019ll add another parameter called <code>ignore<\/code> to our decorator. It\u2019s similar to <code>include<\/code>, but is a blacklist instead of a whitelist.<\/p>\n<p>Lastly, we want to get rid of that hard-coded attribute name, <code>\"delegate\"<\/code>. Why? Because you should almost never hard code anything like that, and because there\u2019s a chance that someone might try to double up on the delegate pattern, delegating to two different objects of different classes. We\u2019d end up with trying to store two different delegates in the same attribute. So we need to give the user the option to make the name whatever they want. We\u2019ll still default it to <code>\"delegate\"<\/code> though, so the user won\u2019t have to set it if they don\u2019t need to.<\/p>\n<p>All this leaves us with the final product!<\/p>\n<pre class=\" brush:php\">def delegate_as(delegate_cls, to='delegate', include=frozenset(), ignore=frozenset()):\r\n    # turn include and ignore into a sets, if they aren't already\r\n    if not isinstance(include, Set):\r\n        include = set(include)\r\n    if not isinstance(ignore, Set):\r\n        ignore = set(ignore)\r\n    delegate_attrs = set(delegate_cls.__dict__.keys())\r\n    attributes = include | delegate_attrs - ignore\r\n\r\n    def inner(cls):\r\n        # create property for storing the delegate\r\n        setattr(cls, to, SimpleProperty())\r\n        # don't bother adding attributes that the class already has\r\n        attrs = attributes - set(cls.__dict__.keys())\r\n        # set all the attributes\r\n        for attr in attrs:\r\n            setattr(cls, attr, DelegatedAttribute(to, attr))\r\n        return cls\r\n    return inner<\/pre>\n<p>I also made <code>include<\/code> and <code>ignore<\/code> have default values of an empty <code>set<\/code>. They\u2019re <code>frozenset<\/code>s specifically, despite the fact that the code doesn\u2019t try to mutate them, as a precautionary measure to prevent any future changes from doing so. You might have noticed that the checking of the default parameters is a little different than is typical. That\u2019s because I didn\u2019t make the default parameters default to <code>None<\/code>. I made them default to something I can use.<\/p>\n<p>Also, I generally expect that people will be passing in <code>list<\/code>s or <code>tuple<\/code>s more often than <code>set<\/code>s, so I just made sure that they ended up being a subclass of <code>Set<\/code> (the ABC, since neither <code>frozenset<\/code> nor <code>set<\/code> are subclasses of the other, and users may use some nonstandard <code>Set<\/code>) so I can do the union and subtraction with them later. It also ensures no doubles anywhere.<\/p>\n<h2><b>Moving Forward<\/b><\/h2>\n<p>While I\u2019ve shown the final working product, there\u2019s still some refactoring that could be done to make the code cleaner. For instance, you could take all those comments and use Extract Method to make the actual code say such things. If I were to do that, I\u2019d probably change the whole thing to a callable decorator class, rather than a decorator function.<\/p>\n<h2><b>Outro<\/b><\/h2>\n<p>That was a relatively long article. I could have just shown the final product to you and explained it, but I thought that going through a thought process with it would be nice, too. Are there any changes that you would recommend? What do you guys think of this? Is it worth it?<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/programmingideaswithjake.wordpress.com\/2015\/05\/23\/python-decorator-for-simplifying-delegate-pattern\/\">Python Decorator for Simplifying Delegate Pattern<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/wcg\/\">WCG partner<\/a> Jacob Zimmerman at the <a href=\"http:\/\/programmingideaswithjake.wordpress.com\/\">Programming Ideas With Jake<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick description, the pattern has you inherit from the parent interface (or, in Python, you can just implement the protocol), but all the methods either redirect to calling the method on an &hellip;<\/p>\n","protected":false},"author":51,"featured_media":1651,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53],"tags":[198],"class_list":["post-4953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","tag-design-patterns"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-06-08T15:45:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jacob Zimmerman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/jacobz_20\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jacob Zimmerman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\"},\"author\":{\"name\":\"Jacob Zimmerman\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39\"},\"headline\":\"Python Decorator for Simplifying Delegate Pattern\",\"datePublished\":\"2015-06-08T15:45:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\"},\"wordCount\":1488,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"keywords\":[\"Design Patterns\"],\"articleSection\":[\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\",\"name\":\"Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"datePublished\":\"2015-06-08T15:45:20+00:00\",\"description\":\"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/python\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Python Decorator for Simplifying Delegate Pattern\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39\",\"name\":\"Jacob Zimmerman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g\",\"caption\":\"Jacob Zimmerman\"},\"description\":\"Jacob is a certified Java programmer (level 1) and Python enthusiast. He loves to solve large problems with programming and considers himself pretty good at design.\",\"sameAs\":[\"https:\/\/programmingideaswithjake.wordpress.com\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/jacobz_20\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/jacob-zimmerman\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026","description":"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/","og_locale":"en_US","og_type":"article","og_title":"Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026","og_description":"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick","og_url":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2015-06-08T15:45:20+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","type":"image\/jpeg"}],"author":"Jacob Zimmerman","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/jacobz_20","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Jacob Zimmerman","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/"},"author":{"name":"Jacob Zimmerman","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39"},"headline":"Python Decorator for Simplifying Delegate Pattern","datePublished":"2015-06-08T15:45:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/"},"wordCount":1488,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","keywords":["Design Patterns"],"articleSection":["Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/","url":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/","name":"Python Decorator for Simplifying Delegate Pattern - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","datePublished":"2015-06-08T15:45:20+00:00","description":"Recently, I posted about how you can use composition instead of inheritance, and in that article, I mentioned the Delegate Pattern. As a quick","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/python\/python-decorator-simplifying-delegate-pattern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Python","item":"https:\/\/www.webcodegeeks.com\/category\/python\/"},{"@type":"ListItem","position":3,"name":"Python Decorator for Simplifying Delegate Pattern"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39","name":"Jacob Zimmerman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g","caption":"Jacob Zimmerman"},"description":"Jacob is a certified Java programmer (level 1) and Python enthusiast. He loves to solve large problems with programming and considers himself pretty good at design.","sameAs":["https:\/\/programmingideaswithjake.wordpress.com\/","https:\/\/x.com\/https:\/\/twitter.com\/jacobz_20"],"url":"https:\/\/www.webcodegeeks.com\/author\/jacob-zimmerman\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/4953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=4953"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/4953\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/1651"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=4953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=4953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=4953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}