Есть ли более эффективный метод создания объекта класса Python с дополнительными параметрами? - PullRequest
0 голосов
/ 16 июня 2020

Я новичок в Python и подозреваю, что могу перенести старые привычки из VB. NET.

Я пытаюсь создать планировщик задач, который будет читать введенные задача вместе с необязательными параметрами «дата» и «приоритет», разделенными «//». Таким образом, входная строка может выглядеть следующим образом:

Do something // 16-6-20 // 1
Do something // 16-6-20
Do something

Я создал класс с именем Task с четырьмя свойствами: t, date, priority и checked (последнее не имеет значения для целей вопроса.) Когда пользователь вводит строку ввода, строка разделяется и обрезается, и создается новый объект класса. Это код:

from dateutil import parser
from datetime import datetime

class Task:
    def __init__(self, _t, _date=None, _priority=None, _checked=False):
        self.t = _t
        self.date = _date
        self.priority = _priority
        self.checked = _checked

while True:
    print("Add a new task/event:")
    taskstr = input("> ")
    info = [x.strip() for x in taskstr.split("//")]

    t = ""
    date = None
    priority = None

    if len(info) == 1:
        t = info[0]
    elif len(info) == 2:
        t = info[0]
        date = parser.parse(info[1], dayfirst=True)
    elif len(info) == 3:
        t = info[0]
        date = parser.parse(info[1], dayfirst=True)
        priority = info[2]

    newtask = Task(t, date, priority)
    print(newtask.t, newtask.date, newtask.priority)

Итак, мой вопрос прост: является ли это эффективным методом создания экземпляра объекта Python, когда у меня есть два необязательных параметра, или есть лучший / более "Pythony" способ сделать это? Есть какой-то трюк, который мне не хватает? Код работает, но я не уверен, что он лучший.

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Использование * args может пропустить множество решений для переменной длины данных.

from dateutil import parser
from datetime import datetime

class Task:
    def __init__(self, _t, _date=None, _priority=None, _checked=False):
        self.t = _t
        self.date =  parser.parse(_date, dayfirst=True) if _date else None
        self.priority = _priority
        self.checked = _checked

while True:
    print("Add a new task/event:")
    try:
        taskstr = input("> ")
    except:
        break
    info = [x.strip() for x in taskstr.split("//")]
    newtask = Task(*info)
    print(newtask.t, newtask.date, newtask.priority)
1 голос
/ 16 июня 2020

Вы можете использовать *args и **kwargs, но в целом в вашем исходном подходе нет ничего плохого. Пожалуйста, обратитесь к этой статье, которая довольно хорошо объясняет функциональность *args и **kwargs https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

EDIT: вполне нормально использовать *args и *kwargs в init, и он неплохо работает с наследованием. Рассмотрим следующий пример:

class  Foo:
    def __init__(self,foo=None,bar=None,*args,**kwargs):
        self.foo = foo
        self.bar = bar

class Bar(Foo):
    def __init__(self, required, optional = None, *args, **kwargs):
        self.required = required
        self.optional = optional
        self.barkwarg = kwargs.get('barkwarg')
        super().__init__(*args,**kwargs)

if __name__ == "__main__":
    bar1 = Bar(0,1,2,3,4)
    bar2 = Bar(0,1,barkwarg=2,foo=3,bar=4)

если вы распечатаете атрибуты, вы увидите, что аргументы были распакованы и переданы базовому классу.

    print("bar1.required: ",bar1.required)  # required:  0
    print("bar1.optional: ",bar1.optional)  # optional:  1
    print("bar1.barkwarg: ",bar1.barkwarg)  # barkwarg:  None
    print("bar1.foo: ",bar1.foo)            # foo:  2 
    print("bar1.bar: ",bar1.bar)            # bar:  3

    print("bar2.required: ",bar2.required)  # required:  0
    print("bar2.optional: ",bar2.optional)  # optional:  1
    print("bar2.barkwarg: ",bar2.barkwarg)  # barkwarg:  2 
    print("bar2.foo: ",bar2.foo)            # foo:  2
    print("bar2.bar: ",bar2.bar)            # bar:  3

Вам также не нужно if при работе с kwargs, но вы можете использовать метод dictionary.get(keyname, value), поскольку kwargs - это просто словарь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...