在一个对象中添加多个变量 - 需要进一步的帮助

Adding multiple variables in an object - need further assistance

首先 - 根据建议,请尽量让新手可以理解,因为它太复杂了,它可能没有太大用处,因为我需要在当前问题之后进一步继续。提前谢谢你:)

我正在尝试定义一个包含多个我可能会用到的变量的对象。 到目前为止,我能够为自己创建基本的 class(仅使用对象的 ID),但我现在正在努力添加对象所需的其余变量。

我要用对象的多实例存储的数据如下:

引用我的示例数据:

PersonID: ID1234
Name: Anton Todorov
Started at: 2022-12-26T00:00:00+02:00
Ended at: 2022-12-26T02:00:00+02:00
Schedule ID: SCHEDID1
Contacts: ['a.todorov@e-mail.email', 359, '000000000']
---===Separator===---
PersonID: ID5678
Name: Morgan Freeman
Started at: 2022-12-26T02:00:00+02:00
Ended at: 2022-12-26T14:00:00+02:00
Schedule ID: SCHEDID2
Contacts: ['slogan@draftkings.com', 1, '0000000000']
---===Separator===---
PersonID: ID1234
Name: Anton Todorov
Started at: 2022-12-26T14:00:00+02:00
Ended at: 2022-12-27T02:00:00+02:00
Schedule ID: SCHEDID3
Contacts: ['a.todorov@e-mail.email', 359, '000000000']

因此,我必须根据我拥有的这些数据部分计算每个人花费的总小时数。

目前我的对象如下:

class DataItem(object):
    def __init__(self, person_id):
        self._person_id = person_id

        self._updatable_id = ""

    @property
    def person_id(self):
        return self._person_id

    @property
    def updatable_id(self):
        return self._updatable_id

    @updatable_id.setter
    def updatable_id(self, value):
        self._updatable_id = value

    @updatable_id.deleter
    def updatable_id(self):
        del self._updatable_id


class Persons(object):
    def __init__(self):
        self._ids = []

    def find_person_by_id(self, person_id):
        # search by id
        existing = [i for i in self._ids if i.person_id == person_id]

        if not existing:
            # create and append
            existing_person = DataItem(id)
            self._ids.append(existing_person)

        else:
            # assign to existing
            existing_person = existing[0]

        # return the object to be acted upon
        return existing_person

所以..有人可以帮助我进一步开发该对象,以便我可以将数据正确地存储在它的每个实例中吗?

我很乐意感谢所有详细的建议(尤其是当我也能够理解它们时)。

提前谢谢大家!

根据你正在做的事情,我会考虑做 json 数据格式并做这样的事情。请原谅我快速而肮脏的代码,但我认为从根本上说,您正在寻找一种方法来创建可能适用于您的场景的数据格式。

又看了一遍,感觉这可能就是你要找的格式

[
    {
        "person_id": "ID1234",
        "name": "Anton Todorov",
        "schedule": [
            {
                "schedule_id": "SCHEDID1",
                "started_at": "2022-12-26T00:00:00+02:00",
                "ended_at": "2022-12-26T02:00:00+02:00"
            },
            {
                "schedule_id": "SCHEDID3",
                "started_at": "2022-12-26T14:00:00+02:00",
                "ended_at": "2022-12-27T02:00:00+02:00"
            }
        ],
        "contact_info": {
            "email": "a.todorov@e-mail.email",
            "country_code": 359,
            "phone_number": "000000000"
        }
    },
    {
        "person_id": "ID5678",
        "name": "Morgan Freeman",
        "schedule": [
            {
                "schedule_id": "SCHEDID2",
                "started_at": "2022-12-26T02:00:00+02:00",
                "ended_at": "2022-12-26T14:00:00+02:00"
            }
        ],
        "contact_info": {
            "email": "slogan@draftkings.com",
            "country_code": 1,
            "phone_number": "000000000"
        }
    }
]

代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json

def main():
    people = list()

    person = dict()
    person['person_id'] = 'ID1234'
    person['name'] = 'Anton Todorov'
    person['schedule'] = list()
    schedule = dict()
    schedule['schedule_id'] = 'SCHEDID1'
    schedule['started_at'] = '2022-12-26T00:00:00+02:00'
    schedule['ended_at'] = '2022-12-26T02:00:00+02:00'
    person['schedule'].append(schedule)
    schedule = dict()
    schedule['schedule_id'] = 'SCHEDID3'
    schedule['started_at'] = '2022-12-26T14:00:00+02:00'
    schedule['ended_at'] = '2022-12-27T02:00:00+02:00'
    person['schedule'].append(schedule)
    contact_info = dict()
    contact_info['email'] = 'a.todorov@e-mail.email'
    contact_info['country_code'] = 359
    contact_info['phone_number'] = '000000000'
    person['contact_info'] = contact_info
    people.append(person)

    person = dict()
    person['person_id'] = 'ID5678'
    person['name'] = 'Morgan Freeman'
    person['schedule'] = list()
    schedule = dict()
    schedule['schedule_id'] = 'SCHEDID2'
    schedule['started_at'] = '2022-12-26T02:00:00+02:00'
    schedule['ended_at'] = '2022-12-26T14:00:00+02:00'
    person['schedule'].append(schedule)
    contact_info = dict()
    contact_info['email'] = 'slogan@draftkings.com'
    contact_info['country_code'] = 1
    contact_info['phone_number'] = '000000000'
    person['contact_info'] = contact_info
    people.append(person)


    print(json.dumps(people, indent=4))

if __name__ == '__main__':
    main()

我终于开发出了我想要的东西。 有点乱,但这正是我需要的。

感谢@Robert Lee 的尝试,尽管这不是我选择继续的。

class PersonData(object):
    def __init__(self, email, country_code, phone_number, user_id, names):
        self._email = email
        self._country_code = country_code
        self._phone_number = phone_number
        self._user_id = user_id
        self._names = names
        self._started = []
        self._ended = []
        self._schedule_id = []

    @property
    def email(self):
        return self._email

    @property
    def country_code(self):
        return self._country_code

    @property
    def phone_number(self):
        return self._phone_number

    @property
    def user_id(self):
        return self._user_id

    @property
    def names(self):
        return self._names

    @property
    def started(self):
        return self._started

    @started.setter
    def started(self, started):
        self._started.append(started)

    @started.deleter
    def started(self):
        del self._started

    @property
    def ended(self):
        return self._ended

    @ended.setter
    def ended(self, ended):
        self._ended.append(ended)

    @ended.deleter
    def ended(self):
        del self._ended

    @property
    def schedule_id(self):
        return self._schedule_id

    @schedule_id.setter
    def schedule_id(self, schedule_id):
        self._schedule_id.append(schedule_id)

    @schedule_id.deleter
    def schedule_id(self):
        del self._schedule_id


class PeopleBuffer(object):
    def __init__(self):
        self._people = []

    def find_by_id(self, email, country_code, phone_number, user_id, names):
        # search by id
        existing = [i for i in self._people if i.user_id == user_id]

        if not existing:
            # create and append if not found
            existing_person = PersonData(email, country_code, phone_number, user_id, names)
            self._people.append(existing_person)
        else:
            # assign to existing
            existing_person = existing[0]

        # return an object to be acted upon
        return existing_person

    def return_all(self):
        for each_person in self._people:
            print("each_person: ")
            print("Email: %s" % each_person.email)
            print("Country Code: %s" % each_person.country_code)
            print("Phone Number: %s" % each_person.phone_number)
            print("User Id: %s" % each_person.user_id)
            print("Names: %s" % each_person.names)
            print("Started: %s" % each_person.started)
            print("Ended: %s" % each_person.ended)
            print("ScheduleId: %s" % each_person.schedule_id)


class MainApplication(object):
    def __init__(self):
        self._buffer = PeopleBuffer()

    def _populate_person(self, email, country_code, phone_number, user_id, names, started, ended, schedule_id):
        person = self._buffer.find_by_id(email, country_code, phone_number, user_id, names)
        person.started.append(started)
        person.ended.append(ended)
        person.schedule_id.append(schedule_id)

    def _print_people(self):
        self._buffer.return_all()

    def main(self):

        while input("Continue? ") != "No":

            user_id = input("Enter UserId: ")
            names = input("Enter Name: ")
            started = input("Enter Started: ")
            ended = input("Enter Ended: ")
            schedule_id = input("Enter ScheduleId: ")
            email = input("Enter Email: ")
            country_code = input("Enter CountryCode: ")
            phone_number = input("Enter PhoneNumber: ")

            self._populate_person(email, country_code, phone_number, user_id, names, started, ended, schedule_id)

        self._print_people()


def main():
    app = MainApplication()
    app.main()


if __name__ == '__main__':
    main()

要事第一;您的示例感觉更像是用 Python 编写的 Java 示例。实例变量实际上是属性,因此您的所有 @property 方法都是冗余代码。


dataclasses 模块是针对像您这样的情况实施的。例如,

计划数据class:

# schedule.py

from dataclasses import dataclass, field
from datetime import datetime
from typing import Union


@dataclass(unsafe_hash=True)
class Schedule:
    schedule_id: str
    start: Union[str, datetime]
    end: Union[str, datetime]
    
    def __post_init__(self):
        self.start = self._datetime_converter(self.start)
        self.end = self._datetime_converter(self.end)
    
    def _datetime_converter(self, dt: str):
        return datetime.strptime(dt, '%Y-%m-%dT%H:%M:%S+02:00')
    
    def overlaps_with(self, other: Schedule):
        return not ((self.start >= other.end) ^ (other.start >= self.end))
    
    @property
    def deltatime(self):
        return self.end - self.start

工人数据class:

# worker.py

from functools import reduce
from dataclasses import dataclass, field
from .schedule import Schedule


@dataclass
class Worker:
    person_id: str
    name: str
    contacts: str = field(repr=False)
    schedules: set[Schedule] = field(init=False, default_factory=set)
    email: str = field(init=False, default='')
    country: int = field(init=False, default=-1)
    phone: str = field(init=False, default='')
    
    def __post_init__(self):
        self.email, self.country, self.phone = self.contacts
    
    @classmethod
    def add_from_json(cls, worker_id: str, file: str):
        NotImplemented
    
    def overlapping_schedules(self, schedule: Schedule):
        return filter(lambda s: s.overlaps_with(schedule), self.schedules)
    
    def schedule_overlaps(self, schedule: Schedule):
        return any(self.overlapping_schedules(schedule))
    
    def add_schedule(self, schedule: Schedule):
        if not self.schedule_overlaps(schedule):
            self.schedules.update({schedule})
        else:
            NotImplemented
    
    def add_schedules_from_json(self, file: str):
        NotImplemented
        
    def remove_schedule(self, schedule: Schedule):
        self.schedules -= {schedule}
    
    @property
    def total_time_scheduled(self):
        deltas = map(lambda s: s.deltatime, self.schedules)
        return reduce(lambda x, y: x + y, deltas)
        
    def __hash__(self):
        return hash(id(self.person_id))
    
    def __eq__(self, other):
        return self.person_id == other.person_id

从理论上讲,您实际上并不需要创建 Workers class。 __hash____eq__ 方法会处理这个问题,您只需要创建一个 set[Worker]。但是,如果您仍想创建 Workers class,只需循环现有方法即可。