creating package structure

This commit is contained in:
Roman Mogilatov 2015-01-04 16:26:33 +02:00
parent 9cfc1e8b6e
commit aea9d2b3eb
5 changed files with 214 additions and 47 deletions

View File

@ -2,3 +2,63 @@ Objects
======= =======
Python catalogs of objects providers. Python catalogs of objects providers.
Example:
```python
import objects
import sqlite3
class A(object):
def __init__(self, db):
self.db = db
class B(object):
def __init__(self, a, db):
self.a = a
self.db = db
class Catalog(objects.Catalog):
"""
Objects catalog.
"""
database = objects.Singleton(sqlite3.Connection,
database='example.db')
""" :type: (objects.Provider) -> sqlite3.Connection """
object_a = objects.NewInstance(A,
db=database)
""" :type: (objects.Provider) -> A """
object_b = objects.NewInstance(B,
a=object_a,
db=database)
""" :type: (objects.Provider) -> B """
class Consumer(object):
catalog = Catalog(Catalog.object_a,
Catalog.object_b)
def return_a_b(self):
return (self.catalog.object_a(),
self.catalog.object_b())
a1, b1 = Consumer().return_a_b()
a2 = Catalog.object_a()
b2 = Catalog.object_b()
print a1, a1.db
print a2, a2.db
print b1, b1.db
print b2, b2.db
assert a1 is not a2
assert b1 is not b2
```

View File

@ -36,10 +36,15 @@ class Catalog(objects.Catalog):
""" :type: (objects.Provider) -> B """ """ :type: (objects.Provider) -> B """
catalog = Catalog(Catalog.object_a, class Consumer(object):
catalog = Catalog(Catalog.object_a,
Catalog.object_b) Catalog.object_b)
a1 = catalog.object_a()
b1 = catalog.object_b() def return_a_b(self):
return (self.catalog.object_a(),
self.catalog.object_b())
a1, b1 = Consumer().return_a_b()
a2 = Catalog.object_a() a2 = Catalog.object_a()
b2 = Catalog.object_b() b2 = Catalog.object_b()

View File

@ -2,48 +2,10 @@
`Objects` library. `Objects` library.
""" """
from .catalog import Catalog
class Catalog(object): from .std_providers import (Provider, NewInstance, Singleton, Class, Object,
def __init__(self, *args): Function, Value)
args = set(args)
for attribute_name in set(dir(self.__class__)) - set(dir(Catalog)):
provider = getattr(self, attribute_name)
if not isinstance(provider, Provider):
continue
if provider not in args:
setattr(self, attribute_name, None)
class Provider(object): __all__ = ['Catalog', 'Provider', 'NewInstance', 'Singleton', 'Class',
def __call__(self, *args, **kwargs): 'Object', 'Function', 'Value']
raise NotImplementedError()
class NewInstance(Provider):
def __init__(self, provides, **dependencies):
self.provides = provides
self.dependencies = dependencies
def __call__(self, *args, **kwargs):
for name, dependency in self.dependencies.iteritems():
if name in kwargs:
continue
if isinstance(dependency, Provider):
value = dependency.__call__()
else:
value = dependency
kwargs[name] = value
return self.provides(*args, **kwargs)
class Singleton(NewInstance):
def __init__(self, *args, **kwargs):
self.instance = None
super(Singleton, self).__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
if not self.instance:
self.instance = super(Singleton, self).__call__(*args, **kwargs)
return self.instance

32
objects/catalog.py Normal file
View File

@ -0,0 +1,32 @@
"""
Catalog module.
"""
from .std_providers import Provider
class Catalog(object):
"""
Object provides catalog.
"""
def __init__(self, *used_providers):
"""
Initializer.
"""
self._clean_unused_providers(used_providers)
def _clean_unused_providers(self, used_providers):
"""
Sets every catalog's provider in None except of `used_providers` list.
:param list|tuple|set used_providers:
:return:
"""
used_providers = set(used_providers)
for attribute_name in set(dir(self.__class__)) - set(dir(Catalog)):
provider = getattr(self, attribute_name)
if not isinstance(provider, Provider):
continue
if provider not in used_providers:
setattr(self, attribute_name, None)

108
objects/std_providers.py Normal file
View File

@ -0,0 +1,108 @@
"""
Standard providers.
"""
class Provider(object):
"""
Base provider class.
"""
def __call__(self, *args, **kwargs):
"""
Returns provided instance.
"""
raise NotImplementedError()
class NewInstance(Provider):
"""
New instance providers will create and return new instance on every call.
"""
def __init__(self, provides, **dependencies):
"""
Initializer.
"""
self.provides = provides
self.dependencies = dependencies
def __call__(self, *args, **kwargs):
"""
Returns provided instance.
"""
for name, dependency in self.dependencies.iteritems():
if name in kwargs:
continue
if isinstance(dependency, Provider):
value = dependency.__call__()
else:
value = dependency
kwargs[name] = value
return self.provides(*args, **kwargs)
class Singleton(NewInstance):
"""
Singleton provider will create instance once and return it on every call.
"""
def __init__(self, *args, **kwargs):
"""
Initializer.
"""
self.instance = None
super(Singleton, self).__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
"""
Returns provided instance.
"""
if not self.instance:
self.instance = super(Singleton, self).__call__(*args, **kwargs)
return self.instance
class _StaticProvider(Provider):
"""
Static provider is base implementation that provides exactly the same as
it got on input.
"""
def __init__(self, provides):
"""
Initializer.
"""
self.provides = provides
def __call__(self):
"""
Returns provided instance.
"""
return self.provides
class Class(_StaticProvider):
"""
Class provider provides class.
"""
class Object(_StaticProvider):
"""
Object provider provides object.
"""
class Function(_StaticProvider):
"""
Function provider provides function.
"""
class Value(_StaticProvider):
"""
Value provider provides value.
"""