First, most of the time when you think you need something like that, you do not; this is a sign that you're trying to treat Python as Java, and the solution is to step back and ask why you need a factory.
Often the simplest thing is to simply create a constructor with default / optional / keyword arguments. Even cases that you will never write in Java, even cases where overloaded constructors will not feel right in C ++ or ObjC, may seem completely natural in Python. For example, size = Size(bytes=20) or size = Size(20, Size.BYTES) look reasonable. In this case, the Bytes(20) class, which inherits from Size and adds absolutely nothing, but the __init__ overload looks reasonable. And this is trivial:
def __init__(self, *, bits=None, bytes=None, kilobits=None, kilobytes=None):
Or:
BITS, BYTES, KILOBITS, KILOBYTES = 1, 8, 1024, 8192
But sometimes you need factory functions. So what are you doing then? Well, there are two types of things that are often combined into "factories."
A @classmethod is an idiomatic way to execute an "alternative constructor" - there are examples for all stdlib- itertools.chain.from_iterable , datetime.datetime.fromordinal , etc.
A function is an idiomatic way of making a "I don't care what the actual class is" factory. Take a look, for example, at the built-in open function. Do you know what it returns in 3.3? You care? Nope. That is why it is a function, not io.TextIOWrapper.open or something else.
Your given example seems to be quite a legitimate precedent and fits very clearly into the bit of the alternative constructor (if it does not fit into the "constructor with additional arguments" bin).