0

I know that private attributes are loosely defined in Python, but I'm trying to figure out what would be the most lean way of implementing a method to merge together private attributes.

Class Event:
  target_time: datetime
  _names: set

I'm thinking of having a static method to merge together two Events.

@staticmethod
def merge(event1: Event, event2: Event) -> Event:
  new_event = Event()
  new_event._names = event1._names + event2._names
  return new_event

But I'm unsure if this breaks some good design patterns about private attribute since they are private.

6
  • 1
    If merge is a method on Event, then this is totally fine. Commented Jun 28, 2023 at 9:42
  • So something like this ? ``` def merge(self, other_event: Event) -> Event: new_event = Event() new_event = self._names + other_event._names return new_event ``` Commented Jun 28, 2023 at 11:41
  • Yes, but also as a static method as shown in the question is fine too. (Except that new_event = Event() in both your examples appears to be superfluous?!) What concern do you have about the above code? Commented Jun 28, 2023 at 11:44
  • Since it's within a static method, it seems to mean that I'm accessing internal attributes of an object which I maybe should avoid ? Commented Jun 28, 2023 at 11:59
  • 1
    The method is part of the class that defines the attribute. The class is expected to know how to treat those protected attributes correctly. It isn't limited to only accessing that attribute on self. Commented Jun 28, 2023 at 12:02

1 Answer 1

0

Errors in code

1. @staticmethod
2. def merge(event1: Event, event2: Event) -> Event:
3.   new_event = Event()
4.   new_event = event1._names + event2._names
5.  return new_event
  • new_event in lines 3 and 4 are different types, Event and set respectively.
  • new_event in line 5 doesn't match with declared return-type.

Suggestion

Use Python data model. Create new Event using syntax new_event = event1 + event2 by implementing __add__ method.

Suggested Implementation

from datetime import datetime, timedelta

class Event:
    target_time: datetime
    _names: set

    def __init__(self, target_time: datetime, names: set):
        self.target_time = target_time
        self._names = names
    
    def __add__(self, other):
        # set new time as you like
        new_time = self.target_time if self.target_time > other.target_time else other.target_time
        new_event = Event(
            new_time,
            self._names | other._names
            )
        return new_event

    def __str__(self):
        return f"{self._names} @ {self.target_time}\n"

Now you can merge Events like this:

tonight = datetime.today().replace(hour=21, minute=0, second=0, microsecond=0)
tomor_night = tonight+timedelta(hours=24)
yest_night =  tonight+timedelta(hours=-24)

event1 = Event(tonight, {"Get", "Set", "Go"})
event2 = Event(tomor_night, {"Get", "Set", "Again"})
event3 = Event(yest_night, {"Got" "It"})

new_event = event1 + event2 + event3

print(event1, event2, event3, new_event)

output:

{'Set', 'Go', 'Get'} @ 2023-07-07 21:00:00
{'Set', 'Again', 'Get'} @ 2023-07-08 21:00:00
{'GotIt'} @ 2023-07-06 21:00:00
{'GotIt', 'Go', 'Set', 'Again', 'Get'} @ 2023-07-08 21:00:00
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for flagging this, just an oversight in my example code to explain my question about design patterns, not really about the merge itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.