Автоматическая установка переменных класса класса в Python

Скажем, у меня есть следующий класс в Python

class Foo(object): a = None b = None c = None def __init__(self, a = None, b = None, c = None): self.a = a self.b = b self.c = c 

Есть ли способ упростить этот процесс? Всякий раз, когда я добавляю новый член в класс Foo, я вынужден изменить конструктор.

  • Аргументы Python как словарь
  • Использование pandas .append внутри цикла for
  • Pandas: Как создать кадр данных случайных чисел?
  • Как я могу получить текущее семя генератора случайных чисел NumPy?
  • Определить повторяющиеся значения в списке в Python
  • Неверный ответ в SPOJ `CUBERT`
  • Заменить слова в строке словами из списка, используя python
  • Конструировать 3d-массив в numpy из существующего массива 2d
  • 3 Solutions collect form web for “Автоматическая установка переменных класса класса в Python”

    Обратите внимание, что

     class Foo(object): a = None 

    устанавливает пару ключ-значение в Foo :

     Foo.__dict__['a']=None 

    в то время как

     def __init__(self, a = None, b = None, c = None): self.a = a 

    устанавливает пару ключ-значение в файле объекта экземпляра Foo:

     foo=Foo() foo.__dict__['a']=a 

    Поэтому установка членов класса в верхней части вашего определения напрямую не связана с настройкой атрибутов экземпляра в нижней половине вашего определения (внутри __init__ .

    Кроме того, хорошо знать, что __init__ является инициализатором Python. __new__ – это конструктор класса.


    Если вы ищете способ автоматического добавления атрибутов экземпляра на основе аргументов __init__ , вы можете использовать это:

     import inspect import functools def autoargs(*include,**kwargs): def _autoargs(func): attrs,varargs,varkw,defaults=inspect.getargspec(func) def sieve(attr): if kwargs and attr in kwargs['exclude']: return False if not include or attr in include: return True else: return False @functools.wraps(func) def wrapper(self,*args,**kwargs): # handle default values for attr,val in zip(reversed(attrs),reversed(defaults)): if sieve(attr): setattr(self, attr, val) # handle positional arguments positional_attrs=attrs[1:] for attr,val in zip(positional_attrs,args): if sieve(attr): setattr(self, attr, val) # handle varargs if varargs: remaining_args=args[len(positional_attrs):] if sieve(varargs): setattr(self, varargs, remaining_args) # handle varkw if kwargs: for attr,val in kwargs.iteritems(): if sieve(attr): setattr(self,attr,val) return func(self,*args,**kwargs) return wrapper return _autoargs по import inspect import functools def autoargs(*include,**kwargs): def _autoargs(func): attrs,varargs,varkw,defaults=inspect.getargspec(func) def sieve(attr): if kwargs and attr in kwargs['exclude']: return False if not include or attr in include: return True else: return False @functools.wraps(func) def wrapper(self,*args,**kwargs): # handle default values for attr,val in zip(reversed(attrs),reversed(defaults)): if sieve(attr): setattr(self, attr, val) # handle positional arguments positional_attrs=attrs[1:] for attr,val in zip(positional_attrs,args): if sieve(attr): setattr(self, attr, val) # handle varargs if varargs: remaining_args=args[len(positional_attrs):] if sieve(varargs): setattr(self, varargs, remaining_args) # handle varkw if kwargs: for attr,val in kwargs.iteritems(): if sieve(attr): setattr(self,attr,val) return func(self,*args,**kwargs) return wrapper return _autoargs 

    Поэтому, когда вы говорите

     class Foo(object): @autoargs() def __init__(self,x,path,debug=False,*args,**kw): pass foo=Foo('bar','/tmp',True, 100, 101,verbose=True) 

    вы автоматически получаете эти атрибуты экземпляра:

     print(foo.x) # bar print(foo.path) # /tmp print(foo.debug) # True print(foo.args) # (100, 101) print(foo.verbose) # True 

    PS. Хотя я написал это (для удовольствия), я не рекомендую использовать autoargs для серьезной работы. Быть явным просто, ясно и непогрешимо. Я не могу сказать то же самое для autoargs .

    PPS. Это только я, или много кнопок, разбитых на Stackoverflow? Окно редактора потеряло все свои значки … 🙁 Очистка кеша браузера устранила проблему.

    Есть изящные способы сделать это.

    Есть ли способ упростить этот процесс? Всякий раз, когда я добавляю новый член в класс Foo, я вынужден изменить конструктор.

    Существует также грубый путь. Он будет работать, но НЕ рекомендуется. Смотрите и решайте.

     >>> class Foo(object): def __init__(self, **attrs): self.__dict__.update(**attrs) def __getattr__(self, attr): return self.__dict__.get(attr, None) >>> f = Foo(a = 1, b = 2, c = 3) >>> fa, fb (1, 2) >>> f = Foo(bar = 'baz') >>> f.bar 'baz' >>> fa >>> 

    Конструктор аргументов ключевого слова позволяет обойтись без явного определения каких-либо аргументов. Предупреждение : это противоречит принципу «явный лучше, чем неявный» .

    Вам нужно переопределить __getattr__ ТОЛЬКО, если вы хотите вернуть значение по умолчанию для атрибута, который отсутствует, вместо получения AttributeError .

    http://code.activestate.com/recipes/286185-automatically-initializing-instance-variables-from/

    Этот рецепт и его комментарии предоставляют некоторые методы.

    Python: автоматически инициализировать переменные экземпляра?

    Это предыдущий вопрос.

    Interesting Posts

    Сравнение двух списков с использованием оператора больше или меньше

    В Python, как мне декодировать кодировку GZIP?

    Почему вложенные функции python не называются замыканиями?

    Python: как продлить datetime.timedelta

    Urllib2 работает нормально, если я запускаю программу самостоятельно, но бросает ошибку, когда добавляю ее в cronjob

    моделирование движения толпы с помощью matplotlib

    Как получить идентификаторы кластера, не являющиеся одиночными, в скудной иерархической кластеризации

    PySpark – временное перекрытие для объекта в RDD

    Может ли SQLAlchemy использоваться с Google Cloud SQL?

    Как извлечь числовые диапазоны из 2 столбцов, содержащих числовые последовательности, и напечатать диапазон из обоих столбцов (разные значения прироста)?

    Почему фрагменты в Python 3 все еще копируются, а не просмотры?

    Лучший способ конвертировать URL-адрес Unicode в ASCII (UTF-8-escaped) в Python?

    Группировать дубликаты идентификаторов столбцов в кадре данных pandas

    Почему не добавляются бинарные соленые огурцы?

    Получить все элементы из очереди потоков

    Python - лучший язык программирования в мире.