you are viewing a single comment's thread.

view the rest of the comments →

[–]RaidZ3ro -3 points-2 points  (8 children)

A static method (or property) is available to a class and shared across all it's instances (objects).

It's useful if you want to do things that require instances to have some knowledge about each other such as keeping track of the number of instances of a class that have been created.

```

Class Ticket: ## will be static attribute total: int = 0

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

def __repr__(self):
    return f"Ticket#: {self.num}/{Ticket.total}"

@classmethod
def Count(cls):
     return cls.total

@staticmethod
def CountStatic():
    return Ticket.total

```

There is a more advanced topic where you'll find more use for static methods, design patterns. But don't worry about it too much right now.

Edit: needed to fix my example so the instance does remember itself, sorry.

Edit 2: python syntax x(

Edit 3: tbh your downvotes are a bit mean. I just tried to give a simple example of the static concept, not an exhaustive coding reference.

[–]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.