decorator approach runs almost 100% faster than the approach using mixins. Now aren’t
you glad you read all the way to the end?
8.14. Implementing Custom Containers
Problem
You want to implement a custom class that mimics the behavior of a common built-in
container  type, such as a list or dictionary.  However, you’re not entirely sure what
methods need to be implemented to do it.
Solution
The collections library defines a variety of abstract base classes that are extremely
useful when implementing custom container classes. To illustrate, suppose you want
your class to support iteration. To do that, simply start by having it inherit from col
lections.Iterable, as follows:
import collections
class A(collections.Iterable):
pass
The special feature about inheriting from collections.Iterable is that it ensures you
implement all of the required special methods. If you don’t, you’ll get an error upon
instantiation:
>>> a = A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeErrorCan't instantiate abstract class A with abstract methods __iter__
>>>
To fix this error, simply give the class the required __iter__() method and implement
it as desired (see Recipes 4.2 and 4.7).
Other notable classes defined in collections include SequenceMutableSequence,
MappingMutableMappingSet, and MutableSet. Many of these classes form hierarchies
with increasing levels of functionality (e.g., one such hierarchy is Container, Itera
bleSizedSequence, and MutableSequence). Again, simply instantiate any of these
classes to see what methods need to be implemented to make a custom container with
that behavior:
>>> import collections
>>> collections.Sequence()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeErrorCan't instantiate abstract class Sequence with abstract methods \
8.14. Implementing Custom Containers  |  283
Pdf add signature field - C# PDF File Permission Library: add, remove, update PDF file permission in C#.net, ASP.NET, MVC, WPF
Tell C# users how to set PDF file permissions, like printing, copying, modifying, extracting, annotating, form filling, etc
pdf converter sign in; sign pdf online
Pdf add signature field - VB.NET PDF File Permission Library: add, remove, update PDF file permission in vb.net, ASP.NET, MVC, WPF
VB.NET Tutorial for How to Set PDF File Access Permissions Using XDoc.PDF for .NET
pdf create signature; adding a signature to a pdf file
__getitem__, __len__
>>>
Here is a simple example of a class that implements the preceding methods to create a
sequence where items are always stored in sorted order (it’s not a particularly efficient
implementation, but it illustrates the general idea):
import collections
import bisect
class SortedItems(collections.Sequence):
def __init__(selfinitial=None):
self._items = sorted(initial) if initial is None else []
# Required sequence methods
def __getitem__(selfindex):
return self._items[index]
def __len__(self):
return len(self._items)
# Method for adding an item in the right location
def add(selfitem):
bisect.insort(self._itemsitem)
Here’s an example of using this class:
>>> items = SortedItems([513])
>>> list(items)
[1, 3, 5]
>>> items[0]
1
>>> items[-1]
5
>>> items.add(2)
>>> list(items)
[1, 2, 3, 5]
>>> items.add(-10)
>>> list(items)
[-10, 1, 2, 3, 5]
>>> items[1:4]
[1, 2, 3]
>>> 3 in items
True
>>> len(items)
5
>>> for n in items:
...     print(n)
...
-10
1
2
3
284  |  Chapter 8: Classes and Objects
C# PDF Digital Signature Library: add, remove, update PDF digital
things. Add a signature or an empty signature field in any PDF file page. Search unsigned signature field in PDF document. Prepare
add signature to pdf preview; pdf sign
VB.NET PDF Digital Signature Library: add, remove, update PDF
things. Add a signature or an empty signature field in any PDF file page. Search unsigned signature field in PDF document. Prepare
create transparent signature stamp for pdf; adding a signature to a pdf in preview
5
>>>
As you can see, instances of SortedItems behave exactly like a normal sequence and
support all of the usual operations, including indexing, iteration, len(), containment
(the in operator), and even slicing.
As an aside, the bisect module used in this recipe is a convenient way to keep items in
a list sorted. The bisect.insort() inserts an item into a list so that the list remains in
order.
Discussion
Inheriting from one of the abstract base classes in collections ensures that your cus‐
tom container implements all of the required methods expected of the container. How‐
ever, this inheritance also facilitates type checking.
For example, your custom container will satisfy various type checks like this:
>>> items = SortedItems()
>>> import collections
>>> isinstance(itemscollections.Iterable)
True
>>> isinstance(itemscollections.Sequence)
True
>>> isinstance(itemscollections.Container)
True
>>> isinstance(itemscollections.Sized)
True
>>> isinstance(itemscollections.Mapping)
False
>>>
Many of the abstract base classes in collections also provide default implementations
of common container methods. To illustrate, suppose you have a class that inherits from
collections.MutableSequence, like this:
class Items(collections.MutableSequence):
def __init__(selfinitial=None):
self._items = list(initial) if initial is None else []
# Required sequence methods
def __getitem__(selfindex):
print('Getting:'index)
return self._items[index]
def __setitem__(selfindexvalue):
print('Setting:'indexvalue)
self._items[index= value
def __delitem__(selfindex):
8.14. Implementing Custom Containers  |  285
C# PDF insert image Library: insert images into PDF in C#.net, ASP
field. Access to freeware download and online C#.NET class source code. How to insert and add image, picture, digital photo, scanned signature or logo into PDF
create pdf stamp signature; create signature from pdf
VB.NET PDF insert image library: insert images into PDF in vb.net
Import graphic picture, digital photo, signature and logo into PDF Add images to any selected PDF page in VB.NET. Insert images into PDF form field in VB.NET.
add signature to pdf in preview; create signature field in pdf
print('Deleting:'index)
del self._items[index]
def insert(selfindex, value):
print('Inserting:'index, value)
self._items.insert(indexvalue)
def __len__(self):
print('Len')
return len(self._items)
If you create an instance of Items, you’ll find that it supports almost all of the core list
methods (e.g., append()remove(), count(), etc.). These methods are implemented in
such a way that they only use the required ones. Here’s an interactive session that illus‐
trates this:
>>> a = Items([123])
>>> len(a)
Len
3
>>> a.append(4)
Len
Inserting: 3 4
>>> a.append(2)
Len
Inserting: 4 2
>>> a.count(2)
Getting: 0
Getting: 1
Getting: 2
Getting: 3
Getting: 4
Getting: 5
2
>>> a.remove(3)
Getting: 0
Getting: 1
Getting: 2
Deleting: 2
>>>
This recipe only provides a brief glimpse into Python’s abstract class functionality. The
numbers module provides a similar collection of abstract classes related to numeric data
types. See Recipe 8.12 for more information about making your own abstract base
classes.
286  |  Chapter 8: Classes and Objects
How to C#: Basic SDK Concept of XDoc.PDF for .NET
You may add PDF document protection functionality into your C# program. To be specific, you can edit PDF password and digital signature, and set PDF file
pdf to word converter sign in; pdf signature field
VB.NET PDF: Basic SDK Concept of XDoc.PDF
You may add PDF document protection functionality into your VB.NET program. To be specific, you can edit PDF password and digital signature, and set PDF file
pdf signature stamp; pdf signature
8.15. Delegating Attribute Access
Problem
You want an instance to delegate attribute access to an internally held instance possibly
as an alternative to inheritance or in order to implement a proxy.
Solution
Simply stated, delegation is a programming pattern where the responsibility for imple‐
menting a particular operation is handed off (i.e., delegated) to a different object. In its
simplest form, it often looks something like this:
class A:
def spam(self, x):
pass
def foo(self):
pass
class B:
def __init__(self):
self._a = A()
def spam(self, x):
# Delegate to the internal self._a instance
return self._a.spam(x)
def foo(self):
# Delegate to the internal self._a instance
return self._a.foo()
def bar(self):
pass
If there are only a couple of methods to delegate, writing code such as that just given is
easy enough. However, if there are many methods to delegate, an alternative approach
is to define the __getattr__() method, like this:
class A:
def spam(self, x):
pass
def foo(self):
pass
class B:
def __init__(self):
self._a = A()
8.15. Delegating Attribute Access  |  287
VB.NET PDF Library SDK to view, edit, convert, process PDF file
NET program. Password, digital signature and PDF text, image and page redaction will be used and customized. PDF Annotation Edit.
add signature to pdf online; adding a signature to a pdf
C# Create PDF Library SDK to convert PDF from other file formats
you can add some additional information to generated PDF file. What's more, you can also protect created PDF file by adding digital signature (watermark) on
pdf will signature; add signature pdf
def bar(self):
pass
# Expose all of the methods defined on class A
def __getattr__(selfname):
return getattr(self._aname)
The __getattr__() method is kind of like a catch-all for attribute lookup. It’s a method
that gets called if code tries to access an attribute that doesn’t exist. In the preceding
code, it would catch access to undefined methods on B and simply delegate them to A.
For example:
b = B()
b.bar()    # Calls B.bar() (exists on B)
b.spam(42# Calls B.__getattr__('spam') and delegates to A.spam
Another example of delegation is in the implementation of proxies. For example:
# A proxy class that wraps around another object, but
# exposes its public attributes
class Proxy:
def __init__(selfobj):
self._obj = obj
# Delegate attribute lookup to internal obj
def __getattr__(selfname):
print('getattr:'name)
return getattr(self._obj, name)
# Delegate attribute assignment
def __setattr__(selfnamevalue):
if name.startswith('_'):
super().__setattr__(namevalue)
else:
print('setattr:'namevalue)
setattr(self._objnamevalue)
# Delegate attribute deletion
def __delattr__(selfname):
if name.startswith('_'):
super().__delattr__(name)
else:
print('delattr:'name)
delattr(self._objname)
To use this proxy class, you simply wrap it around another instance. For example:
class Spam:
def __init__(selfx):
self.x = x
def bar(selfy):
print('Spam.bar:'self.xy)
288  |  Chapter 8: Classes and Objects
C# PDF Convert to Images SDK: Convert PDF to png, gif images in C#
image files including all PDF contents, like watermark and signature in .NET. C#.NET DLLs Solution for Converting Images to PDF in C# Add necessary references:
create pdf signature box; add jpeg signature to pdf
C# PDF remove image library: remove, delete images from PDF in C#.
Support removing vector image, graphic picture, digital photo, scanned signature, logo, etc. Remove Image from PDF Page Using C#. Add necessary references:
pdf add signature field; click to sign pdf
# Create an instance
s = Spam(2)
# Create a proxy around it
p = Proxy(s)
# Access the proxy
print(p.x)     # Outputs 2
p.bar(3      # Outputs "Spam.bar: 2 3"
p.x = 37       # Changes s.x to 37
By customizing the implementation of the attribute access methods, you could cus‐
tomize the proxy to behave in different ways (e.g., logging access, only allowing read-
only access, etc.).
Discussion
Delegation is sometimes used as an alternative to inheritance. For example, instead of
writing code like this:
class A:
def spam(self, x):
print('A.spam'x)
def foo(self):
print('A.foo')
class B(A):
def spam(self, x):
print('B.spam')
super().spam(x)
def bar(self):
print('B.bar')
A solution involving delegation would be written as follows:
class A:
def spam(self, x):
print('A.spam'x)
def foo(self):
print('A.foo')
class B:
def __init__(self):
self._a = A()
def spam(self, x):
print('B.spam'x)
self._a.spam(x)
8.15. Delegating Attribute Access  |  289
def bar(self):
print('B.bar')
def __getattr__(selfname):
return getattr(self._aname)
This use of delegation is often useful in situations where direct inheritance might not
make much sense or where you want to have more control of the relationship between
objects (e.g., only exposing certain methods, implementing interfaces, etc.).
When using delegation to implement proxies, there are a few additional details to note.
First, the __getattr__() method is actually a fallback method that only gets called when
an attribute is not found. Thus, when attributes of the proxy instance itself are accessed
(e.g.,  the _obj  attribute),  this  method  would  not  be  triggered.  Second,  the __se
tattr__() and __delattr__() methods need a bit of extra logic added to separate
attributes from the proxy instance inself and attributes on the internal object _obj. A
common convention is for proxies to only delegate to attributes that don’t start with a
leading underscore (i.e., proxies only expose the “public” attributes of the held instance).
It is also important to emphasize that the __getattr__() method usually does not apply
to most special methods that start and end with double underscores. For example, con‐
sider this class:
class ListLike:
def __init__(self):
self._items = []
def __getattr__(selfname):
return getattr(self._itemsname)
If you try to make a ListLike object, you’ll find that it supports the common list meth‐
ods, such as append() and insert(). However, it does not support any of the operators
like len(), item lookup, and so forth. For example:
>>> a = ListLike()
>>> a.append(2)
>>> a.insert(01)
>>> a.sort()
>>> len(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeErrorobject of type 'ListLike' has no len()
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError'ListLike' object does not support indexing
>>>
To support the different operators, you have to manually delegate the associated special
methods yourself. For example:
290  |  Chapter 8: Classes and Objects
class ListLike:
def __init__(self):
self._items = []
def __getattr__(selfname):
return getattr(self._itemsname)
# Added special methods to support certain list operations
def __len__(self):
return len(self._items)
def __getitem__(selfindex):
return self._items[index]
def __setitem__(selfindexvalue):
self._items[index= value
def __delitem__(selfindex):
del self._items[index]
See Recipe 11.8 for another example of using delegation in the context of creating proxy
classes for remote procedure call.
8.16. Defining More Than One Constructor in a Class
Problem
You’re writing a class, but you want users to be able to create instances in more than the
one way provided by __init__().
Solution
To define a class with more than one constructor, you should use a class method. Here
is a simple example:
import time
class Date:
# Primary constructor
def __init__(selfyearmonthday):
self.year = year
self.month = month
self.day = day
# Alternate constructor
@classmethod
def today(cls):
t = time.localtime()
return cls(t.tm_yeart.tm_mon, t.tm_mday)
To  use the alternate constructor, you simply call it  as a function, such as Date.to
day(). Here is an example:
8.16. Defining More Than One Constructor in a Class  |  291
a = Date(20121221)      # Primary
b = Date.today()            # Alternate
Discussion
One of the primary uses of class methods is to define alternate constructors, as shown
in this recipe. A critical feature of a class method is that it receives the class as the first
argument (cls). You will notice that this class is used within the method to create and
return the final instance. It is extremely subtle, but this aspect of class methods makes
them work correctly with features such as inheritance. For example:
class NewDate(Date):
pass
c = Date.today()      # Creates an instance of Date (cls=Date)
d = NewDate.today()   # Creates an instance of NewDate (cls=NewDate)
When defining a class with multiple constructors, you should make the __init__()
function as simple as possible—doing nothing more than assigning attributes from
given values. Alternate constructors can then choose to perform advanced operations
if needed.
Instead of defining a separate class method, you might be inclined to implement the
__init__() method in a way that allows for different calling conventions. For example:
class Date:
def __init__(self*args):
if len(args== 0:
t = time.localtime()
args = (t.tm_yeart.tm_mon, t.tm_mday)
self.yearself.monthself.day = args
Although this technique works in certain cases, it often leads to code that is hard to
understand and difficult to maintain. For example, this implementation won’t show
useful help strings (with argument names). In addition, code that creates Date instances
will be less clear. Compare and contrast the following:
a = Date(20121221)   # Clear. A specific date.
b = Date()               # ??? What does this do?
# Class method version
c = Date.today()         # Clear. Today's date.
As shown, the Date.today() invokes the regular Date.__init__() method by instan‐
tiating a Date() with suitable year, month, and day arguments. If necessary, instances
can be created without ever invoking the __init__() method. This is described in the
next recipe.
292  |  Chapter 8: Classes and Objects
Documents you may be interested
Documents you may be interested