Horrible abuse of __init_subclass__, or elegant hack?
jak
nospam at please.ty
Sun Apr 4 04:24:21 EDT 2021
Il 01/04/2021 01:14, Chris Angelico ha scritto:
> I think this code makes some sort of argument in the debate about
> whether Python has too much flexibility or if it's the best
> metaprogramming toolset in the world. I'm not sure which side of the
> debate it falls on, though.
>
> class Building:
> resource = None
> @classmethod
> def __init_subclass__(bldg):
> super().__init_subclass__()
> print("Building:", bldg.__name__)
> def make_recipe(recip):
> print(recip.__name__.replace("_", " "), "is made in a",
> bldg.__name__.replace("_", " "))
> bldg.__init_subclass__ = classmethod(make_recipe)
>
>
> class Extractor(Building): ...
> class Refinery(Building): ...
>
> class Crude(Extractor):
> resource = "Oil"
> time: 1
> Crude: 1
>
> class Plastic(Refinery):
> Crude: 3
> time: 6
> Residue: 1
> Plastic: 2
>
> class Rubber(Refinery):
> Crude: 3
> time: 6
> Residue: 2
> Rubber: 2
>
> Full code is here if you want context:
> https://github.com/Rosuav/shed/blob/master/satisfactory-production.py
>
> Subclassing Building defines a class that is a building. (The ellipsis
> body is a placeholder; I haven't implemented stuff where the buildings
> know about their power consumptions and such. Eventually they'll have
> other attributes.) But subclassing a building defines a recipe that is
> produced in that building. Markers placed before the "time" are
> ingredients, those after the "time" are products.
>
> There are actually a lot of interesting wrinkles to trying to replace
> __init_subclass__ on the fly. Things get quite entertaining if you
> don't use the decorator, or if you define and decorate the function
> outside of the class, or various other combinations.
>
> On a scale of 1 to "submit this to The Daily WTF immediately", how bad
> is this code? :)
>
> ChrisA
>
Hi,
from https://github.com/Rosuav/shed/blob/master/satisfactory-production.py
I get this error:
cmd console Win10:
$> py -V
Python 3.8.6
$> py CrisAngelico.py
Building: Extractor
Building: Refinery
Building: Blender
Building: Packager
Building: Assembler
Crude is made in a Extractor
Water is made in a Extractor
Plastic is made in a Refinery
Rubber is made in a Refinery
Traceback (most recent call last):
File "CrisAngelico.py", line 123, in <module>
class Rubber(Refinery):
File "CrisAngelico.py", line 72, in make_recipe
if net <= alternate["makes"] and costs >= alternate["costs"]:
TypeError: '<=' not supported between instances of 'Counter' and 'Counter'
:^(
More information about the Python-list
mailing list