2015-01-27 16:53:17 +00:00
.. _examples:
Examples
========
2015-01-28 15:28:47 +00:00
The simplest possible usage would be:
.. doctest ::
>>> import attr
>>> @attr.s
... class Empty(object):
... pass
>>> Empty()
Empty()
>>> Empty() == Empty()
True
>>> Empty() is Empty()
False
So in other words: `` attrs `` useful even without actual attributes!
But you'll usually want some data on your classes, so let's add some:
.. doctest ::
>>> @attr.s
... class Coordinates(object):
... x = attr.ib()
... y = attr.ib()
These by default, all features are added, so you have immediately a fully functional data class with a nice `` repr `` string and comparison methods.
.. doctest ::
>>> c1 = Coordinates(1, 2)
>>> c1
Coordinates(x=1, y=2)
>>> c2 = Coordinates(x=2, y=1)
>>> c2
Coordinates(x=2, y=1)
>>> c1 == c2
False
As shown, the generated `` __init__ `` method allows both for positional and keyword arguments.
2015-01-28 16:36:58 +00:00
2015-01-29 09:17:08 +00:00
If playful naming turns you off, `` attrs `` comes with no-nonsense aliases:
.. doctest ::
>>> @attr.attributes
... class SeriousCoordinates(object):
... x = attr.attr()
... y = attr.attr()
>>> SeriousCoordinates(1, 2)
SeriousCoordinates(x=1, y=2)
>>> attr.ls(Coordinates) == attr.ls(SeriousCoordinates)
True
2015-01-28 16:36:58 +00:00
Sometimes you want to have default values for your initializer.
And sometimes you even want mutable objects as default values (ever used accidentally `` def f(arg=[]) `` ?).
`` attrs `` has you covered in both cases:
.. doctest ::
>>> import collections
>>> @attr.s
... class Connection(object):
... socket = attr.ib()
... @classmethod
... def connect(cl, db_string):
... # connect somehow to db_string
... return cl(socket=42)
>>> @attr.s
... class ConnectionPool(object):
... db_string = attr.ib()
... pool = attr.ib(default_factory=collections.deque)
... debug = attr.ib(default_value=False)
... def get_connection(self):
... try:
... return self.pool.pop()
... except IndexError:
... if self.debug:
... print "New connection!"
... return Connection.connect(self.db_string)
... def free_connection(self, conn):
... if self.debug:
... print "Connection returned!"
... self.pool.appendleft(conn)
...
>>> cp = ConnectionPool("postgres://localhost")
>>> cp
ConnectionPool(db_string='postgres://localhost', pool=deque([]), debug=False)
>>> conn = cp.get_connection()
>>> conn
Connection(socket=42)
>>> cp.free_connection(conn)
>>> cp
ConnectionPool(db_string='postgres://localhost', pool=deque([Connection(socket=42)]), debug=False)
More information on why class methods for constructing objects are awesome can be found in this insightful `blog post <http://as.ynchrono.us/2014/12/asynchronous-object-initialization.html> `_ .