25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

154 satır
5.1 KiB

Bu dosya muğlak Evrensel Kodlu karakter içeriyor!

Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek muğlak Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Bu karakterleri göstermek için Kaçış düğmesine tıklayın.

import os
from functools import wraps
from abc import ABCMeta, abstractmethod
from inspect import getcallargs
class Cachable:
'''Базовый класс для создания классов, кэширующих вывод своих методов.
Декоратор @Cachable.method_cached() предназначен для указания методов
с кэшируемым выводом.'''
def __init__(self):
self.clear_method_cache()
def clear_method_cache(self):
self._method_cache = {}
@staticmethod
def method_cached(key=lambda *args, **kwargs: hash(args)):
def decorator(function):
function_name = function.__name__
@wraps(function)
def wrapper(self, *args, **kwargs):
keyval = key(*args, **kwargs)
assert isinstance(self, Cachable)
if function_name not in self._method_cache:
self._method_cache[function_name] = {}
cache = self._method_cache[function_name]
if keyval not in cache:
cache[keyval] = function(self, *args, **kwargs)
return cache[keyval]
@wraps(function)
def null_wrapper(self):
assert isinstance(self, Cachable)
if function_name not in self._method_cache:
self._method_cache[function_name] = function(self)
return self._method_cache[function_name]
if len(function.__code__.co_varnames) > 1:
return wrapper
else:
return null_wrapper
return decorator
class Singleton(type):
'''Метакласс для создания синглтонов.'''
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class SingletonParam(type):
'''Метакласс для создания синглтонов по параметрам.'''
_instances = {}
_init = {}
def __init__(cls, class_name, base_classes, class_dict):
cls._init[cls] = class_dict.get('__init__', None)
def __call__(cls, *args, **kwargs):
init = cls._init[cls]
if init is not None:
key_value = (cls, frozenset(getcallargs(init, None, *args,
**kwargs).items()))
else:
key_value = cls
if key_value not in cls._instances:
cls._instances[key_value] = super().__call__(*args, **kwargs)
return cls._instances[key_value]
class GenericFS(metaclass=ABCMeta):
'''Абстрактный класс для работы с файловыми системами.'''
@abstractmethod
def exists(self, path):
pass
@abstractmethod
def read(self, path):
pass
@abstractmethod
def glob(self, path):
pass
@abstractmethod
def realpath(self, path):
pass
@abstractmethod
def write(self, path, data):
pass
@abstractmethod
def listdir(self, path, fullpath=False):
pass
def get_traceback_caller(exception_type, exception_object,
exception_traceback):
'''Возвращает имя модуля, в котором было сгенерировано исключение,
и соответствующий номер строки.'''
while exception_traceback.tb_next:
exception_traceback = exception_traceback.tb_next
line_number = exception_traceback.tb_lineno
module_path, module_name = os.path.split(exception_traceback.tb_frame.
f_code.co_filename)
if module_name.endswith('.py'):
module_name = module_name[:-3]
full_module_name = [module_name]
while (module_path and module_path != '/' and not
module_path.endswith('site-packages')):
module_path, package_name = os.path.split(module_path)
full_module_name.insert(0, package_name)
if module_path.endswith('site-packages'):
module_name = '.'.join(full_module_name)
return module_name, line_number
def unique(iterable):
'''Возвращает итерируемый объект, содержащий только уникальные элементы
входного объекта, сохраняя их порядок.
'''
output = []
for element in iterable:
if element not in output:
output.append(element)
return output
def flat_iterable(iterable, types=(list, tuple, map, zip, filter)):
'''Распаковывает все вложенные итерируемые объекты во входном объекте.
Например:
[1, 2, [3, 4, [5, 6], 7], [8, 9], 10] -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
'''
if isinstance(iterable, types):
for it in iterable:
for sub_iterable in flat_iterable(it, types=types):
yield sub_iterable
else:
yield iterable