-1

I read this method in a repository by huggingface:

@staticmethod
def from_file(vocab: str, **kwargs):
    vocab = WordPiece.read_file(vocab)
    return BertWordPieceTokenizer(vocab, **kwargs)

It returns an instantiation of a class, then I wonder why not classmethod?

Lerner Zhang
  • 6,184
  • 2
  • 49
  • 66
  • Maybe you should attempt to answer your own question first. Why would you even think that this method should be a `@classmethod`? – quamrana Sep 18 '21 at 15:39
  • A `@classmethod` receives an additional parameter to let it know which subclass it was invoked on, and would typically use that parameter to create an instance of that particular subclass. For a method that creates an instance of some hard-coded class, making it a classmethod would be pointless. – jasonharper Sep 18 '21 at 15:40
  • `It returns an instantiation of a class` That's not what makes a classmethod... – John Gordon Sep 18 '21 at 16:44
  • @JohnGordon What about e.g. [`dict.fromkeys`](https://docs.python.org/3/library/stdtypes.html#dict.fromkeys)? – ekhumoro Sep 18 '21 at 16:54
  • @ekhumoro I don't understand. Sure, a classmethod _can_ return a class instance, but that does not _make_ it a classmethod, which the questioner seemed to think was the case. – John Gordon Sep 18 '21 at 19:22
  • @JohnGordon It could also be interpreted as a question about the *design* of the method. It seems natural to ask why the author of the code chose to do things that way. Is there some specific reason why the method hard-codes the returned type? – ekhumoro Sep 18 '21 at 22:24

1 Answers1

1

I will assume that you expect it to be like this:

@classmethod
def from_file(cls, vocab: str, **kwargs):
    vocab = WordPiece.read_file(vocab)
    return cls(vocab, **kwargs)

The problem with this is that for each inheriting class it will use that class to instantiate an object rather than BertWordPieceTokenizer. I would think they don't want that to be the case, because it will be error-prone and easily break things on child classes.

saedx1
  • 984
  • 6
  • 20
  • Surely it's much more unintuitive and error-prone for it *not* to return an of object of the same class? I would expect it to be *way* more common for `from*` methods to always preserve type. That's how e.g. `dict.fromkeys` behaves, and the same goes for many of the classes found in stdlib modules (e.g. `datetime`, `fractions`, `collections`, etc). For the rare occasions when the type has to be hard-coded, a module-level function should always be preferred. Using a `staticmethod` in those situations just invites confusion. – ekhumoro Sep 18 '21 at 16:23
  • Yes, I expect it to be that. I cannot find any benefits of the hard coded instantiation in that huggingface scenario. – Lerner Zhang Sep 19 '21 at 00:35
  • 1
    @LernerZhang I think the author probably just didn't consider subclassing, so it's a design bug in their implementation. – ekhumoro Sep 21 '21 at 12:57