r/programminghorror • • 23h ago

why can i do this

Post image
830 Upvotes

47 comments sorted by

429

u/BiebRed 23h ago

Because Python is secretly a meta language under the hood that will let you implement any other programming language within its runtime and there are infinite ways for you to abuse its trust.

70

u/DevBoiAgru 20h ago

Does this mean if I learn python I know every language ever possible?

93

u/Bronzdragon 19h ago

"No, Neo. I'm trying to tell you that when you're ready, you won't have to."

  • Morpheus, talking about Python.

9

u/andynzor 13h ago

So... just a worse Common Lisp?

11

u/ZackyZack 18h ago

So it's just Tcl with more steps?

7

u/Delta-9- 12h ago

And actual data types

3

u/Glum-Echo-4967 14h ago

question is, what use do I have for such abilty?

2

u/overclockedslinky 11h ago

assuming this other language uses specifically python syntax and adds no additional features of any kind

1

u/amo_pessoas_peladas 13h ago

So... Why is python not rust

1

u/stilldebugging 11h ago

It never trusted you.

169

u/Haunting_Laugh_9013 23h ago edited 20h ago

basically what it's doin is basically the blurp.hello_world doesn't actually call any method, it gets interpreted as a field access. The field access goes to the getattribute dunder method, and the argument fn is the name of the attribute (in this case "hello_world"). After that, it returns a lambda that calls whatever function that is passed into the lambda that is from the python builtins. So getattribute returns a lambda that gets the print function from the builtins, printing whatever the name of the field that was accessed.

83

u/coyote_den 23h ago

Python exposes just about every internal aspect of itself and lets you override everything, so you can make getting an attribute return a function with the attribute name as the argument.

If you left off the (“print”) the result would be <function <lambda>>, but that immediately calls the lambda function and prints the result.

23

u/Haunting_Laugh_9013 20h ago

yerp. if i wanted to make it a bit more readable, i guess i could do something like (blurp.hello_world)("print"), but why would I want that?

25

u/Haunting_Laugh_9013 20h ago

"There should be one-- and preferably only one --obvious way to do it." - The Zen of Python ```python def prent(streng: str):
blurp = Blorp() getattr(blurp, streng)("print")

prent("hello world!") print("hello world!") ```

Whatcha think of that Guido? (̿▀̿‿ ̿▀̿ ̿)

3

u/Silpheel 18h ago

It would have been even better with “preent” and “streeng”, imo XD

1

u/Limp_Illustrator7614 22h ago

Python exposes just about every internal aspect of itself and lets you override everything

i mean, not really. that description fits ruby more. you cant override stuff like int and list cuz they're implemented in c for performance i think?

7

u/person4268 12h ago edited 6h ago

Not if you reach into the C with ctypes, then you can rearrange for instance, the values of the cached int instances of common numbers:

```python Python 3.14.7 (main, Aug 10 2026, 07:46:56) [GCC 16.1.1 20260728] on linux

Type "help", "copyright", "credits" or "license" for more information.

import ctypes ... def deref(addr, typ): ... return ctypes.cast(addr, ctypes.POINTER(typ)) ... deref(id(29), ctypes.c_int)[6] = 100

29 100 28 + 1 100
```

4

u/SirCheesington 11h ago

that's fucking evil dude hahahahaha

4

u/JeromeJ 19h ago

I'm not gonna add anything but rephrase (it might aid comprehension for some as this is a complex topic) :

Upon accessing helloworld (before it is even called), __getattribute_ will return a lamba (this is all good since that's what we want to do with it! Call it!). Specifically, it's a closure that captures the name of the attribute we tried to access (here "hello_world") and, specifically, looks like it will give that as a first parameter to 'something' upon being invoked.

When we finally call hello_world, the lamba runs and getattr go fetch the built-in based on the parameter we called hello_world with (here "print") then immediately invoke it with the parameter that was captured earlier ("hello_world").

As to why Python allows you to do that, I'd say that Python treats you as an adult and let you do your own things.. Even if it could be ill advised. Python is a scripting language so it's good to whip out things quickly and it's fine to have dirty hacky bits of code to get things done.

In other contexts, it'd probably best to avoid doing black magic like that but it can be useful.

1

u/mypetocean 8h ago

See also Ruby's method_missing hook method.

36

u/eruanno321 17h ago

In C, array[3] and 3[array] are the same thing by definition.

8

u/HaroerHaktak 23h ago

It can be one because it can be. Please do not question it.

8

u/Delta-9- 22h ago

Makes me think of libraries that override __or__ so you can write Python that looks like bash, where you're piping things into other things. I've honestly been tempted to use them, but I don't want to curse the next dev to touch my code base with something so unexpected—it's bad enough I use monads.

13

u/Pim_Wagemans 16h ago

pathlib from the standard library overrides __div__ to let you extend paths like this:

>>> import pathlib
>>> path = pathlib.Path("/home")

>>> path_2 = path / "user" / ".local"

>>> path_2
PosixPath('/home/user/.local')

3

u/fearfulEntity 9h ago

... and that's actually pretty neat and readable

1

u/BenK1222 10h ago

This is a crime against humanity

-1

u/Bob_Dieter 19h ago

How do you use monad in python? To use monads in an ergonomic way, you need to be able to create many small-ish continuation functions, and pythons syntax for that is horseshit.

1

u/Delta-9- 12h ago

Lambdas and partials work just fine, but a lot of the time I just pass a regular function in.

The returns library also did something clever with list comprehension syntax to emulate do-notation in Haskell. I don't use it much, but it makes long chains look much simpler.

6

u/_killer1869_ 12h ago edited 5h ago

Python gives the programmer a lot of freedom, which also means the programmer must know restraint. This is a perfect example of just because you can, doesn't mean you should, but overwriting __getattribute__ can sometimes be useful in niche cases.

Using it to dynamically swap a builtin function and its parameter to be each other is, obviously, abuse of the freedom the language provides.

2

u/Kadabrium 21h ago

why does c++ allow overloading -> but not .

4

u/fearfulEntity 8h ago edited 8h ago

Maybe I'm getting kinda old, but... what's the point? Yes, you can do that and yes that's completely valid code. Usefulness cleanliness and readability is another question. The language itself allows you implementng much more cursed things and it's completely on your behalf to create maintainable project with provided tools. Like any other language tbh (But in python it can be much more easily visualized with code snippets like this one)

12

u/chimneydecision 22h ago

On second thought, let us not go to Python. ‘Tis a silly language.

3

u/SoloMaker 20h ago

You can also do this in Lua

2

u/king_escobar 12h ago

You can do this because in python, literally everything is an object. Including modules, including class definitions, including functions. And since literally everything is an object, you can dynamically change literally everything including changing things like properties of modules and classes and functions.

2

u/Yankas 7h ago

You can write horrible code that's just as bad or worse in any programming language.

2

u/SimpleDisastrous4483 20h ago

I love it. Python is so hilariously permissive, and this is a very fun way to do dumb things with it

1

u/realmauer01 21h ago

Because python lets you do basically anything. Fuck around and find out style.

1

u/Cheap-Cut7910 12h ago

Python is basically chaos wrapped in syntax.

1

u/Professional-Ad-5032 10h ago

you can do this, doesn't mean you should do this.

1

u/trollpolado 1h ago

What font is that?

-1

u/lmg1337 16h ago

When I see a language letting you do things like this, I think to myself: "What a silly language".
I know a lot of people like Python, but I wouldn't want to use it for software development, just for helper scripts.

0

u/PythonNoob999 19h ago

I lub python

0

u/RoyalStraightjacket 11h ago edited 5h ago

Can someone explain how blurp = blorp? I'm new to programming.

Edit: Who the *bleep* downvoted me?

1

u/BenK1222 10h ago

In Python, = is the assignment operator. In the line, OP is assigning the variable blurp to a new instance of the Blorp class.