Вы не можете использовать аргументы ключевого слова для этого. Если вы принимаете их с помощью обычных параметров, как вы пробовали, единственным порядком является порядок параметров. Если вы принимаете их через **kwargs
, вы получаете dict
(у которого нет порядка).
Если вы хотите знать порядок аргументов, они должны быть позиционными аргументами; это действительно не так.
Однако для этого может быть лучше. Например, почему бы не просто сделать их отдельными методами? Затем, вместо этого:
newfoo = foo.preprocess(resize=(100, 100), cutoff=55)
... вы это делаете:
newfoo = foo.resize(100, 100).cutoff(55)
Или предоставляют простые типы, которые не делают ничего, кроме завернуть аргументы:
newfoo = foo.preprocess(Resize(100, 100), Cutoff(55))
Тогда вам может иметь preprocess
принять свои аргументы *args
и отправить на основе type(arg)
.
И если вы посмотрите на то, как вы бы осуществить это, он указывает на другую возможность:
class DumbArgWrapper(object):
def __init__(self, *args):
self.args = args
class Resize(DumbArgWrapper): pass
class Cutoff(DumbArgWrapper): pass
class Blur(DumbArgWrapper): pass
class ImageProcessor(object):
def preprocess(self, *args):
for arg in args:
if isinstance(arg, Resize):
do_resize(*arg.args)
# etc.
Если вы просто переместить do_resize
код в Resize
(другими словами, сделать это своего рода "ленивая функция" объект), это гораздо чище:
class SmartArgWrapper(object):
def __init__(self, *args):
self.args = args
class Resize(SmartArgWrapper):
def __call__(self, target):
do_resize(target, *self.args)
# etc.
class ImageProcessor(object):
def preprocess(self, *args):
for arg in args:
arg(self)
И, сделав это , вы можете просто создать простую оболочку, которая превращает любую функцию в SmartArtWrapper
вместо того, чтобы создавать кучу подклассов.
А потом ...
Дело в том, есть много возможностей. Для того, кто знает, чего вы хотите и почему, должен быть один и только один очевидный способ сделать это ... но кому-то, кто понятия не имеет, чего вы хотите и почему, это не так.
Почему вы хотите, чтобы это была единственная функция?Это похоже на контр-интуитивный дизайн, и если бы мы знали причины этого, я бы пообещал, что кто-то может придумать лучший дизайн, который бы разрешил те же проблемы. – abarnert
Основная причина в том, что я знаю, что в основном будет поведение по умолчанию, но теперь я узнаю, что, возможно, в некоторых случаях я хотел бы снова переключить порядок. Таким образом, все еще можно кратко называть его как 'preprocess (5, (10,10))', но все же цикл не является полностью детерминированным, и многие длинные имена функций теперь не нужны. – PascalVKooten
Что касается метода 'resize', метода' cutoff', метода 'blur', а затем метода' preprocess', который существует только для (очень распространенного) случая, когда вам нужно от 1 до 3 из них в большинстве общий порядок? Итак, обычно вы просто вызываете 'preprocess (5, (10,10))', но если вы хотите сделать что-то назад, вы будете изменять размер (10, 10) .cutoff (5) '? – abarnert