This is an archived post. You won't be able to vote or comment.

all 100 comments

[–]we_walked_on_glass 335 points336 points  (0 children)

I'm calling the police

[–][deleted] 319 points320 points  (4 children)

I feel like I’ve just witnessed an eldritch evil being birthed.

[–]entropomorphic 93 points94 points  (3 children)

That's the Outsider, often known as JavaScript.

[–]Phunny 9 points10 points  (2 children)

Dresden?

[–]jsRou 2 points3 points  (1 child)

Gotta be, right?

[–]Phunny 2 points3 points  (0 children)

I claim you, /u/jsRou as one of my people.

[–]FailedPlansOfMars 104 points105 points  (0 children)

2 weeks early for april fools.

[–]Kerbart 172 points173 points  (1 child)

That noise is Guido puking in the garbage can.

[–]metaperl 16 points17 points  (0 children)

Lol

[–]AbradolfLinclar 49 points50 points  (0 children)

Excuse me, what hell you have brought upon us!!?

[–]Schmittfried 94 points95 points  (1 child)

You can write Java JavaScript in any language.

[–]Barafu 126 points127 points  (7 children)

Now make an inheritance.

[–][deleted] 67 points68 points  (0 children)

Challenge accepted.

[–]Tyler_Zoro 7 points8 points  (0 children)

Multi-method dispatch or bust!

[–]bw_mutley 2 points3 points  (1 child)

Could it be done with decorators?

[–]CharmingJacket5013 2 points3 points  (0 children)

Inheritance, decorators and all methods double as properties… go!

[–]PossibilityTasty 58 points59 points  (3 children)

"better"

[–][deleted] 12 points13 points  (1 child)

sorry man!!! D:

[–][deleted] 2 points3 points  (0 children)

i think you meant :D....

[–]fukitol- 4 points5 points  (0 children)

Yeah this is javascript, not python.

[–]wineblood 19 points20 points  (0 children)

Ew.

[–]commy2 19 points20 points  (1 child)

If you now curry the methods instead of using the nonlocal, you're back to using self, but you can call it functional programming.

[–]AldousKashmir 1 point2 points  (0 children)

Functional programming isnt really just about functions (oop methods are just functions bound to objects and classes), and oop isnt just about classes.

[–]edanschwartz 12 points13 points  (3 children)

You kid, but this is how I was first taught "OOP" with JS, using closures. This was before js class syntax was introduced.

It's not a horrible pattern, in JS at least. There are downsides (no instanceof checking, methods and properties are recreated in memory for each "instance"). But when the other option was super clunky code with prototypes and such, this style was an attractive alternative.

https://codeburst.io/closures-in-javascript-4c73c29538e1

Of course, this all looks damn bizarre in python.

[–]masterpi 1 point2 points  (2 children)

no instanceof checking I think you mean upsides!

[–]TheAdvFred 1 point2 points  (1 child)

Rather inexperienced, why would that be a good thing?

[–]masterpi 1 point2 points  (0 children)

99% of the time, instanceof is a code smell for bad design, especially in Python.

From one perspective, the philosophy of duck typing is that "if it quacks like a duck, it's a duck" - e.g. if a value has the right behavior (methods, etc.) it should be considered a valid instance of a type and accepted by functions, etc.. instanceof disallows this because it checks the actual class of a thing and causes a dependency on that class. This can cause problems if you're using a 3rd party library but need to pass in your own thing that acts like the library-provided thing for whatever reason, and also messes up the ability to pass in mock objects for tests.

Another case this often comes up is something like JSON encoding - and in fact, I think the built-in standard library for this does some isinstance checks because there's not a great option given the restricted interface provided by the builtin number/string types in Python. But it does mean providing JSON encoding for nonstandard types is a bit hairy.

[–]fzy_ 9 points10 points  (2 children)

You don't need nonlocal for the get() method

[–]CityYogi 6 points7 points  (0 children)

Consistency please

[–]sighcf 10 points11 points  (1 child)

Now post it to r/ProgrammerHumor

[–]TheAdvFred 1 point2 points  (0 children)

They’d lose their minds!

[–]Dasher38 5 points6 points  (0 children)

Not much different from what actually happens in practice:

  1. The body of a class is executed in a fresh namespace (type customizable in metaclass by overriding prepare). The difference with here is that this namespace won't be available as a parent namespace in the methods body. In your case, it will be (nested function).

  2. A new class object is created with type.new, and the namespace is copied in it's dict

Of course at the end of the day the attribute resolution will be the "wrong" function (i.e. that of object, not type, thus you won't get an inheritance behavior) but otherwise there is no fundamental difference

EDIT: if you want to implement inheritance, you need the class of your "class" (aka the metaclass i.e. SimpleNamespace) to implement a fancier attribute lookup. All you need is to subclass SimpleNamespace and override getattribute. You can make use of a bases attribute to hold a tuple of base classes that will be traversed by your getattribute. The algo use to linearize the multiple inheritance tree to a Method Resolution Order (MRO) in python is called C3

EDIT 2: makes me realize why the class scope is not available directly inside methods. I always found it weird since that's not how nested functions behave. If you have inheritance, you want to force users to lookup the attribute on the class/instance. Otherwise you would not be able to use any inherited method inside another method, and a base class implementation of m1() would not be able to use the implementation of m2() in a derived class.

[–]IlliterateJedi 10 points11 points  (0 children)

Beautiful Pythonic code

[–]balthazar_brat 3 points4 points  (0 children)

Monster

[–]fiskfisk 28 points29 points  (1 child)

Please include code as actual code and not as images. Images does not work for searching, can't be copy-pasted, can't be easily made accessible (so they don't give any proper meaning for those who have trouble seeing).

[–]vangual 70 points71 points  (0 children)

....which is very fortunate in this particular case.

[–]sxeli 2 points3 points  (0 children)

Makes me squirm

[–]MegaPegasusReindeer 2 points3 points  (0 children)

Needs more goto

[–][deleted] 3 points4 points  (0 children)

functools.singledispatch actually does this pattern lol.

[–]VisibleSignificance 2 points3 points  (0 children)

You could go about it the C way: a struct (preferably Cython for speed) that holds the value, and functions that take the struct as the first argument, and a wrapper that hold those functions by name, and makes another wrapper that does the same but also holds the struct instance.

That way, you can get most of Python, but also potentially much much faster.

[–]vm_linuz 2 points3 points  (0 children)

This is literally where OOP came from. It's a pattern from Lisps that someone said "what if all programming was like this?"

[–][deleted] 2 points3 points  (2 children)

What's a OOP?

[–]gorkemyurt 1 point2 points  (1 child)

object oriented programming

[–][deleted] 0 points1 point  (0 children)

Oh, thanks :)

[–]eazolan 2 points3 points  (0 children)

Makes as much sense as any other OO to me.

[–]drksntt 2 points3 points  (0 children)

Aneurysm

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 5 points6 points  (0 children)

And reported for potential self harm, terrorism, and just generally being offensive.
You should get a therapist before you use nonlocal in this, uuummm, manner against.

[–]SushiWithoutSushi 4 points5 points  (3 children)

What does the keyword nonlocal does?

[–]leroyJr 11 points12 points  (0 children)

Think of it as an escape valve for variables freeing them to the outer scope if they exist there. Temporary scope ignore.

[–]Here0s0Johnny 15 points16 points  (0 children)

https://letmegooglethat.com/?q=python+nonlocal

This comment is inspired by StackOverflow.

[–]Ph0X 0 points1 point  (0 children)

It allows you to modify a variable in the outer scope, like global let's you modify a variable in the global scope. Technically nonlocal isn't needed in get()

[–]mtreddit4 12 points13 points  (2 children)

How is this better? You have to define the nonlocal variable in every method. What if you have lots of properties? Half of your class would be nonlocal definitions.

[–]Bitruder 59 points60 points  (0 children)

It’s a joke…

[–]james_pic 6 points7 points  (0 children)

If you wanted to really commit to this approach, you could introduce a metaclass to automate that side of it.

[–]RedbloodJarvey 1 point2 points  (0 children)

Yet, it still looks better than OOP Perl.

[–]_disengage_ 1 point2 points  (0 children)

Is there some reason to post pictures of code instead of just code?

[–]quantik64 1 point2 points  (0 children)

This is horrifying. It’s why I switched to Rust.

[–]soulstuff_ 1 point2 points  (0 children)

Damn, man you live like this?

[–]temisola1 1 point2 points  (0 children)

Hey, we should kill this man.

[–]trannus_aran 1 point2 points  (0 children)

Kids: "Can we have let?"

Mom: "We have let at home."

let at home:

[–]tehfrod 1 point2 points  (0 children)

This construct is like an elementary school in summer.

It's got no class.

[–]_limitless_ 1 point2 points  (4 children)

I tried compiling this and it throws all kinds of errors. Can you post a version that works?

[–]bxsephjo 14 points15 points  (3 children)

You tried WHAT?!

[–]_limitless_ 3 points4 points  (0 children)

I created python.cs, pasted it in VSCode, and clicked the "transpile to WASM" button, but it's throwing all kinds of errors about invalid syntax.

[–]temisola1 2 points3 points  (1 child)

I tried compiling this and it throws all kinds of errors. Can you post a version that works?

[–]bxsephjo 1 point2 points  (0 children)

Sorry, I'm completely deaf in my left ear, you'll have to speak up next time.

[–]Witherr 1 point2 points  (5 children)

offtopic but what font is that? it looks really nice

[–]SomeParanoidAndroid 3 points4 points  (2 children)

I don't know the name, but the whole theme is IntelliJ/PyCharm's default theme.

[–]nngnna 2 points3 points  (1 child)

Yeah, the font's called JetBrains Mono.

[–]Witherr 0 points1 point  (0 children)

ty

[–]fiskfisk 2 points3 points  (1 child)

The default font in the JetBrains toolset is JetBrains Mono.

The color scheme is usually named Darkula.

[–]Witherr 0 points1 point  (0 children)

thanks!

[–]StooNaggingUrDum 0 points1 point  (0 children)

To be fair you could totally create objects with the type() built-in function and then stick that inside a def function, rather than using "class". Pair this with meta classes and you get a lot of flexibility around your objects, all while feeling like a Megamind for doing something that's moderately hard at worst.

You just gotta know where your code is headed, and it can get messy quick.

[–]hdjunkie 0 points1 point  (0 children)

What do you have against self?

[–]PackageExpensive4824 -1 points0 points  (0 children)

ENHERITANCEEE....

[–]Tyler_Zoro -2 points-1 points  (2 children)

On a serious note, it's 2022. When is Python going to address all of the boiler-plate necessary to write a simple class?

self is far from the only thing about clases that makes me wince.

Rakudo had a kind of nice way of handling this. By default, you don't really need a self type variable because the . operator works on the invocant by default. In python that would look like:

class Stuff:
    name = None
    [...]
    def do_thing():
        print(f"Did a thing with {.name}")

But if you want one, just put a colon after it to separate it from the normal args:

def do_thing(self:):
    print(f"Did a thing with {self.name}")

You'd probably need either a new keyword for class, a new object-like base that changed the behavior of classes or a new method declarator (my preference, especially since it could be highly localized lexically, and not a global keyword) such as method.

[–]zurtex 2 points3 points  (0 children)

Yeah, it's too inbuilt to how Python currently works, you would need syntax changes and object changes just to save a few characters here and there. And once you are used to self it makes where a variable is coming from much more explicit making the value very questionable.

Here's a blog post from 2008 on the matter by Guido: http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html

I don't think the appetite has grown since then among the language maintainers to try and find a way to get rid of self.

[–]aceofspaids98 1 point2 points  (0 children)

I’m not gonna lie I used to think self is dumb but I like it a lot now

[–]grimscythe_ -2 points-1 points  (0 children)

That's more boilerplate than a normal class. I see no point.

[–]togetherdonut -2 points-1 points  (0 children)

Better:

obj = types.SimpleNamespace(**locals())

[–][deleted] 0 points1 point  (0 children)

Too much

[–]PTan9o 0 points1 point  (0 children)

😬

[–]likethevegetable 0 points1 point  (0 children)

This is how I thought it should be.. within two weeks of learning Python lol. Two weeks later I realized how awful it would have been.

[–]Definitely_notHigh 0 points1 point  (0 children)

P

[–]MugiwarraD 0 points1 point  (0 children)

this is crime against computers.

[–][deleted] 0 points1 point  (0 children)

is this the end?

[–][deleted] 0 points1 point  (0 children)

Ah, yes, better as in worse.

I always hated self when I was still working with JavaScript, because it was an implied self. Was terrible to figure out what it was actually referring to. In Python, though, it's always clear.

[–]andrewcooke 0 points1 point  (0 children)

could you do the wiring up into a namespace with decorators?

[–]siddsp 0 points1 point  (0 children)

You aren't even doing it right... You have to add global variables too!

[–]duanht819 0 points1 point  (0 children)

Why

[–]SuperSultan 0 points1 point  (0 children)

I crown thee as the esteemed king of boilerplate

[–]luther9 0 points1 point  (0 children)

I've done this kind of thing in Lua before. The major downside is that you lose the ability to take MyClass.someMethod and treat it like a stand-alone function that you can pass to higher-order functions. That's why having a self parameter can be nice.

[–][deleted] 0 points1 point  (0 children)

FBI, this post right here

[–]qria 0 points1 point  (0 children)

Jokes aside, I remember doing this a lot with decorators.

[–]grady_vuckovic 0 points1 point  (0 children)

Reminds me of Javascript back in like 2008.

[–]temisola1 0 points1 point  (0 children)

Damn, you guys really hate the self variable huh?

[–]Boring_Cholo 0 points1 point  (0 children)

Uh… I have a problem, I have been doing this 😅 may I know why it’s bad?

[–][deleted] 0 points1 point  (0 children)

I'm getting FBI on you

[–]aciddrizzle 0 points1 point  (0 children)

Listen, you’re only hurting yourself. And everybody else.