
class UserServiceV1(object): """Example class UserService.""" def __init__(self, user_cls): """Initializer.""" self.user_cls = user_cls super(UserService, self).__init__() # vs class UserServiceV2(object): """Example class UserService.""" user_cls = None def __init__(self): """Initializer.""" super(UserService, self).__init__() # в таком случае: class Admin(User): """Admin user.""" class Client(User): """Client user.""" class Driver(User): """Driver user.""" # код ниже не корректен: admin_service_v2_provider = UserServiceV2 admin_service_v2_provider.user_cls = Admin client_service_v2_provider = UserServiceV2 client_service_v2_provider.user_cls = Client driver_service_v2_provider = UserServiceV2 driver_service_v2_provider.user_cls = Driver # в этом проблема: assert admin_service_v2_provider.user_cls is Driver and client_service_v2_provider.user_cls is Driver # в случае использовании инъекции в конструктор (__init__ у нас в пайтоне) такой проблемы нет, # но нужно писать чуть больше кода: def admin_service_provider(): """Provider admin users service.""" return UserServiceV1(Admin) def client_service_provider(): """Provider client users service.""" return UserServiceV1(Client) def driver_service_provider(): """Provider driver users service.""" return UserServiceV1(Driver) # Как вы видели, у меня это решается вот так: from dependency_injector import providers admin_service_provider = providers.Factory(UserServiceV1, user_cls=Admin) client_service_provider = providers.Factory(UserServiceV1, user_cls=Client) driver_service_provider = providers.Factory(UserServiceV1, user_cls=Driver)
from functools import partial class User(object): """Example class User.""" def __init__(self, id, password): """Initializer.""" self.id = id self.password = password super(User, self).__init__() class UserServiceV1(object): """Example class UserService.""" def __init__(self, user_cls): """Initializer.""" self.user_cls = user_cls super(UserServiceV1, self).__init__() # vs class UserServiceV2(object): """Example class UserService.""" def __init__(self, user_cls): """Initializer.""" self.user_cls = user_cls super(UserServiceV2, self).__init__() # в таком случае: class Admin(User): """Admin user.""" class Client(User): """Client user.""" class Driver(User): """Driver user.""" # код ниже не корректен, но если применить кэрирование: admin_service_v2_provider = partial(UserServiceV2, user_cls=Admin) client_service_v2_provider = partial(UserServiceV2, user_cls=Client) driver_service_v2_provider = partial(UserServiceV2, user_cls=Driver) # и код уменьшается и проблему как ветром сдувает: assert admin_service_v2_provider().user_cls is Admin assert driver_service_v2_provider().user_cls is Driver
"""`Factory` providers init injections example.""" import collections import dependency_injector.providers as providers CreditCard = collections.namedtuple('CreditCard', []) Photo = collections.namedtuple('Photo', []) User = collections.namedtuple('User', ['uid', 'main_photo', 'credit_card']) # User, Photo and CreditCard factories: credit_cards_factory = providers.Factory(CreditCard) photos_factory = providers.Factory(Photo) users_factory = providers.Factory(User, main_photo=photos_factory, credit_card=credit_cards_factory) # Creating several User objects: user1 = users_factory(1) # Same as: user1 = User(1, # main_photo=Photo(), # credit_card=CreditCard()) user2 = users_factory(2) # Same as: user2 = User(2, # main_photo=Photo(), # credit_card=CreditCard()) # Context keyword arguments have priority on keyword argument injections: main_photo = Photo() credit_card = CreditCard() user3 = users_factory(3, main_photo=main_photo, credit_card=credit_card) # Same as: user3 = User(3, # main_photo=main_photo, # credit_card=credit_card)
user1 = users_factory(1) # Same as: user1 = User(1, # main_photo=Photo(), # credit_card=CreditCard())
@partial
class User(object): def __init__(self, id, main_photo, credit_card): """Initializer.""" self.id = id self.main_photo = main_photo self.credit_card = credit_card super(User, self).__init__() class Photo(object): pass class CreditCard(object): pass connector = lambda id: User(id, main_photo=Photo(), credit_card=CreditCard()) # Creating several User objects: user1 = connector(1) # Same as: user1 = User(1, # main_photo=Photo(), # credit_card=CreditCard()) user2 = connector(2) # Same as: user2 = User(2, # main_photo=Photo(), # credit_card=CreditCard()) # Making some asserts: assert user1.id == 1 assert isinstance(user1.main_photo, Photo) assert isinstance(user1.credit_card, CreditCard) assert user2.id == 2 assert isinstance(user2.main_photo, Photo) assert isinstance(user2.credit_card, CreditCard) assert user1.main_photo is not user2.main_photo assert user1.credit_card is not user2.credit_card
rmkСпасибо большое за участие. Тема на самом деле очень интересная. Но вот посмотреть все пока времени нет. Я обязательно отпишу, если у меня появятся вопросы. Спасибо!
получилась ли тема полезной?