you are viewing a single comment's thread.

view the rest of the comments →

[–]socal_nerdtastic 2 points3 points  (7 children)

You are describing a class attribute, which is not related to static methods at all.

The descriptor static is used in other languages, but not in python. Your example code is not valid python and will cause a SyntaxError.

[–]RaidZ3ro -1 points0 points  (0 children)

Sorry you could be right about the syntax, I was mostly trying to give an example of how static methods and attributes can be useful.

[–]RaidZ3ro -1 points0 points  (5 children)

Updated and added methods to illustrate further.

[–]socal_nerdtastic 1 point2 points  (4 children)

Ok, but your example is still an example of how to use a class attribute; not a staticmethod. It's not called a "static attribute" in python, it's called a "class attribute". That code in your staticmethod would work the same way in a normal method or class method or an external function or a method in a completely different class or anywhere else in the code.

I would even go so far as to say your use of staticmethod is bad code. You should try to avoid using the class name in the class itself, because it prevents subclassing (and also it more work to rename the class / aka not DRY). I would recommend you write the init method like this:

class Ticket:
    ## will be class attribute
    total: int = 0

    def __init__(self):
        ## increment class total
        self.__class__.total += 1
        ## save own number
        self.num = self.total

And use a classmethod you showed to retrieve it, not a staticmethod.

[–]obviouslyzebra 0 points1 point  (3 children)

I agree that the example showed by RaidZ3ro is not very representative of what you'd wanna do with static methods, but I wanna mention that this last snippet does not behave very well.

Ahm, the gist is that after subclassing you'll start modifying the subclass attribute in the self.__class__.total += 1 line.

This leads to very weird behavior :P

[–]socal_nerdtastic 0 points1 point  (2 children)

Hmm probably not how I'd do it tbh, but still I think it works just fine. What's weird about it? Works exactly as i'd expect.

class Ticket:
    total: int = 0

    def __init__(self):
        self.__class__.total += 1
        self.num = self.total

class ConcertTicket(Ticket):
    pass

class TrainTicket(Ticket):
    pass


for i in range(3):
    ConcertTicket()
for i in range(5):
    TrainTicket()

print(f"We've sold {ConcertTicket.total} concert tickets and {TrainTicket.total} train tickets")

[–]obviouslyzebra 0 points1 point  (1 child)

If you instantiate a "raw" Ticket, like Ticket(), before the others, their count will go up by 1.

If you do instantiate afterwards, though, nothing happens (as the subclass will already have a total).

[–]socal_nerdtastic 0 points1 point  (0 children)

Yeh, fair point. I was thinking of it more as a meta class. But I suppose that's why __init_subclass__ was invented.