Skip to content

Commit babfa91

Browse files
committed
Add pattern: lazy_evaluation
* add pattern. * update readme, sorted by alphabet.
1 parent e0d0472 commit babfa91

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ Current Patterns:
1919
| [builder](builder.py) | call many little discrete methods rather than having a huge number of constructor parameters |
2020
| [catalog](catalog.py) | general methods will call different specialized methods based on construction parameter |
2121
| [chain](chain.py) | apply a chain of successive handlers to try and process the data |
22+
| [chaining_method](chaining_method.py) | continue callback next object method |
2223
| [command](command.py) | bundle a command and arguments to call later |
2324
| [composite](composite.py) | encapsulate and provide access to a number of different objects |
2425
| [decorator](decorator.py) | wrap functionality with other functionality in order to affect outputs |
2526
| [facade](facade.py) | use one class as an API to a number of others |
2627
| [factory_method](factory_method.py) | delegate a specialized function/method to create instances |
2728
| [flyweight](flyweight.py) | transparently reuse existing instances of objects with similar/identical state |
2829
| [graph_search](graph_search.py) | (graphing algorithms, not design patterns) |
30+
| [lazy_evaluation](lazy_evaluation.py) | lazily-evaluated property pattern in Python |
2931
| [mediator](mediator.py) | an object that knows how to connect other objects and act as a proxy |
3032
| [memento](memento.py) | generate an opaque token that can be used to go back to a previous state |
3133
| [mvc](mvc.py) | model<->view<->controller (non-strict relationships) |
@@ -38,4 +40,3 @@ Current Patterns:
3840
| [strategy](strategy.py) | selectable operations over the same data |
3941
| [template](template.py) | an object imposes a structure but takes pluggable components |
4042
| [visitor](visitor.py) | invoke a callback for all items of a collection |
41-
| [chaining_method](chaining_method.py) | continue callback next object method |

lazy_evaluation.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Lazily-evaluated property pattern in Python.
6+
7+
https://en.wikipedia.org/wiki/Lazy_evaluation
8+
http://stevenloria.com/lazy-evaluated-properties-in-python/
9+
"""
10+
11+
12+
def lazy_property(fn):
13+
"""Decorator that makes a property lazy-evaluated."""
14+
attr_name = '_lazy_' + fn.__name__
15+
16+
@property
17+
def _lazy_property(self):
18+
if not hasattr(self, attr_name):
19+
setattr(self, attr_name, fn(self))
20+
return getattr(self, attr_name)
21+
return _lazy_property
22+
23+
24+
class Person(object):
25+
def __init__(self, name, occupation):
26+
self.name = name
27+
self.occupation = occupation
28+
29+
@lazy_property
30+
def relatives(self):
31+
# Get all relatives, let's assume that it costs much time.
32+
relatives = "Many relatives."
33+
return relatives
34+
35+
36+
def main():
37+
Jhon = Person('Jhon', 'Coder')
38+
print("Name: {0} Occupation: {1}".format(Jhon.name, Jhon.occupation))
39+
print("Before we access `relatives`:")
40+
print(Jhon.__dict__)
41+
print("Jhon's relatives: {0}".format(Jhon.relatives))
42+
print("After we've accessed `relatives`:")
43+
print(Jhon.__dict__)
44+
45+
46+
if __name__ == '__main__':
47+
main()
48+
49+
### OUTPUT ###
50+
# Name: Jhon Occupation: Coder
51+
# Before we access `relatives`:
52+
# {'name': 'Jhon', 'occupation': 'Coder'}
53+
# Jhon's relatives: Many relatives.
54+
# After we've accessed `relatives`:
55+
# {'_lazy_relatives': 'Many relatives.', 'name': 'Jhon', 'occupation': 'Coder'}

0 commit comments

Comments
 (0)