Как заставить функцию использовать ключи dict как переменные для класса? - PullRequest
0 голосов
/ 27 февраля 2020

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

class Example():
   DICT={
   'spam0':1,
   'spam1':2,
   'spam2':3,
   ...
   }
   def __init__(self, **kwargs):
       My_special_function(self, kwargs)  #This is my question

   def output(self):
       print(self.spam0, self.spam1, self.spam2)

x=Example()
x.output()
1 2 3

NOTE

Определенный словарь может различаться по размеру

Ответы [ 2 ]

5 голосов
/ 27 февраля 2020

Вы можете использовать

self.__dict__.update(DICT)

в __init__ (где DICT доступно для __init__; в вашем примере вы бы использовали Example.DICT вместо)

Я иногда используйте эту технику, чтобы избежать явного определения большого количества переменных экземпляра. Однако это немного хаки sh и, вероятно, лучше избегать в большинстве случаев. Например, это усложнит понимание вашего класса для других, читающих ваш код.

(Обратите внимание, что этот метод будет создавать переменные экземпляра, а не переменные класса. Создание таких переменных класса еще менее рекомендуется, поскольку повышенный риск столкновения имен и других недоразумений)

0 голосов
/ 27 февраля 2020

Я видел этот код, но я не знаю, почему он работает, но на самом деле я бы лучше сделал свой собственный, чтобы лучше учиться и понимать python.

import inspect
import itertools as it

def filtered_locals(caller_locals):

    result = caller_locals.copy()
    ignored_local_args = ["self", "kwargs"] 

    for arg in ignored_local_args:
        result.pop(arg, caller_locals)
    return result

def merge_dicts_recursively(*dicts):
    '''
    Creates a dict whose keyset is the union of all the
    input dictionaries.  The value for each key is based
    on the first dict in the list with that key.

    dicts later in the list have higher priority

    When values are dictionaries, it is applied recursively
    '''

    result = dict()
    all_items = it.chain(*[d.items() for d in dicts])
    for key, value in all_items:
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = merge_dicts_recursively(result[key], value)

        else:
            result[key] = value
    return result


def digest_config(obj, kwargs, caller_locals={}):
    """
    Sets init args and CONFIG values as local variables

    The purpose of this function is to ensure that all
    configuration of any object is inheritable, able to
    be easily passed into instantiation, and is attached
    as an attribute of the object.
    """

    # Assemble list of CONFIGs from all super classes

    classes_in_hierarchy = [obj.__class__]
    static_configs = []
    while len(classes_in_hierarchy) > 0:
        Class = classes_in_hierarchy.pop()
        classes_in_hierarchy += Class.__bases__

        if hasattr(Class, "DICT"):
            static_configs.append(Class.DICT)


    # Order matters a lot here, first dicts have higher priority
    caller_locals = filtered_locals(caller_locals)
    all_dicts = [kwargs, caller_locals, obj.__dict__]
    all_dicts += static_configs
    obj.__dict__ = merge_dicts_recursively(*reversed(all_dicts))



class Example():
   DICT={
   'spam0':1,
   'spam1':2,
   'spam2':3
   }
   def __init__(self, **kwargs):
       digest_config(self, kwargs)

   def output(self):
       print(self.spam0, self.spam1, self.spam2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...