0

I want to create a set of classes, each with their own unique name. Something like this:

    class B(object):
        # existing_ids = []
        existing_ids = set()

        @staticmethod
        def create(my_id):
            if my_id not in B.existing_ids:
                # B.existing_ids.append(my_id)
                B.existing_ids.add(my_id)
                # return B(my_id)
            else:
                return None

            # Added block
            if style == 'Ba':
                return Ba(my_id, style)
            else:
                return None

        def __init__(self, my_id):
            self.my_id = my_id
            self.style = style  # Added

        # Added function
        def save(self):
            with open('{}.pkl'.format(self.my_id), 'ab') as f:
                pickle.dump(self.data, f, pickle.HIGHEST_PROTOCOL)

        # Added function
        def foo(self):
            self.data = 'B_data'

    # Added class
    class Ba(B):
        def __init__(self, my_id, style):
            super().__init__(my_id, style)

        def foo(self):
            self.data = 'Ba_data'

    # Edited part
    a = B.create('a', 'Ba')
    b = B.create('b', 'Ba')
    c = B.create('b', 'Ba')

    print(B.existing_ids, a.existing_ids, b.existing_ids, c)
    # {'a', 'b'} {'a', 'b'} {'a', 'b'} None

Is this a good idea? Are there better or other ways to do this?

EDIT: I understand that my example was a bit confusing. I've now updated it a bit to better show what I am trying to achieve. For my problem I will also have class Bb(B), class Bc(B), etc.

This thread seems like the most related:
Static class variables in Python

The basics: Python - Classes and OOP Basics
Metaclasses could be relevant, but it also goes a bit over my head:
What is a metaclass in Python?
Classmethod vs static method:
Meaning of @classmethod and @staticmethod for beginner?
What is the difference between @staticmethod and @classmethod in Python?

Community
  • 1
  • 1
InvaderZim
  • 455
  • 3
  • 10
  • What is your use case? It seems a little more natural for `create` to return an existing object with the given ID rather than `None`. – chepner Jan 25 '16 at 17:16
  • Multitons are bad design no matter how you implement them. What are you really trying to do? – Kevin Jan 25 '16 at 21:35
  • @chepner: I tried to add more info to make it clearer now. – InvaderZim Jan 26 '16 at 19:33
  • @Kevin: Any good read on why? – InvaderZim Jan 26 '16 at 19:34
  • @InvaderZim: `existing_ids` is a global variable. Putting it inside a class doesn't really change that. – Kevin Jan 26 '16 at 20:01
  • @Kevin: And? I like it like this since `B.existing_ids` will be the global. We like namespaces, right? To make it _more_ private I could add an underscore. – InvaderZim Jan 26 '16 at 22:04
  • @InvaderZim: That's not the problem. Your state is global regardless of what you prefix it with. Global state is harder to reason about. Just pull `existing_ids` out into a parameter of your constructor or function that returns B instances. – Kevin Jan 26 '16 at 22:07

1 Answers1

0

At the very least, B.create becomes simpler if you use a set instead of a list to store allocated IDs.

class B(object):
    existing_ids = set()

    @staticmethod
    def create(my_id):
        if my_id not in existing_ids:
            existing_ids.add(my_id)
            return B(my_id)

    def __init__(self, my_id):
        self.my_id = my_id
chepner
  • 497,756
  • 71
  • 530
  • 681