У меня есть следующий простой класс, и мне интересно, есть ли простой способ использовать lambda, decorator или helper method и т. Д., Чтобы избежать дублирования цикла for , который появляется в каждом методе в CODENAMES и ALL_DEFAULTS?

class classproperty(object):
    """
    When used to decorate a method in a class, that method will behave
    like as a class property.
    """
    def __init__(self, f):
        # f - the func that's being decorated
        self.f = f

    def __get__(self, obj, cls):
        # call the func on the class
        return self.f(cls)

class PermissionInfo(object):

    MODELS = ['ticket', 'person', 'role']
    PERMS = ['view', 'add', 'change', 'delete']

    @classproperty
    def CODENAMES(cls):
        codenames = []
        for p in cls.PERMS:
            for m in cls.MODELS:
                codenames.append('{}_{}'.format(p, m))
        return codenames

    @classproperty
    def ALL_DEFAULTS(cls):
        ret = {}

        for p in cls.PERMS:
            for m in cls.MODELS:
                ret["{}_{}".format(p, m)] = False

        return ret

Дублирован для цикла этот раздел каждого метода:

# ...
for p in cls.PERMS:
    for m in cls.MODELS:
#...
2
Aaron Lelevier 13 Дек 2016 в 04:11

3 ответа

Лучший ответ

Вы можете использовать itertools.product внутри вспомогательного метода, чтобы генерировать имена:

from itertools import product

def names(cls):
    yield from ('_'.join(x) for x in product(cls.PERMS, cls.MODELS))

Тогда вы можете изменить свой класс, чтобы использовать его:

@classproperty
def CODENAMES(cls):
    return list(names(cls))

@classproperty
def ALL_DEFAULTS(cls):
    return dict.fromkeys(names(cls), False)
5
niemmi 13 Дек 2016 в 01:32

Вы могли бы использовать что-то вроде:

MODEL_PERMS = list(map(lambda t: "{}_{}".format(t[0],t[1]), itertools.product(MODELS, PERMS)))
0
Aske Doerge 13 Дек 2016 в 01:25
from itertools import product


class PermissionInfo(object):

    MODELS = ['ticket', 'person', 'role']
    PERMS = ['view', 'add', 'change', 'delete']
    PRODUCT = product(PERMS, MODELS)
    CODENAMES = ['{}_{}'.format(p, m) for (p, m) in PRODUCT]
    ALL_DEFAULTS = {codename: False for codename in CODENAMES}

Оооо блестящий: -}

0
Stephane Martin 13 Дек 2016 в 01:32