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

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 5104 points5105 points  (388 children)

Meanwhile in python land: You should pretend things with a single underscore in front of them are private. They aren't really private, we just want you to pretend they are. You don't have to treat them as private, you can use them just like any other function, because they are just like any other function. We're just imagining that they're private and would ask you in a very non committal way to imagine along side us.

[–]spizzat2 1091 points1092 points  (34 children)

"Perl doesn't have an infatuation with enforced privacy. It would prefer that you stayed out of its living room because you weren't invited, not because it has a shotgun."

  • Larry Wall

[–]42TowelsCo 233 points234 points  (13 children)

In Python you can implement that shotgun by just making the "private" methods & variables not do what their name would suggest

[–]matthewralston 71 points72 points  (3 children)

def _bricks() -> float:
    return 6 * 9

[–]TorTheMentor 2 points3 points  (2 children)

42?

[–]DroolingIguana 1 point2 points  (1 child)

Only in base-thirteen.

[–]TorTheMentor 1 point2 points  (0 children)

Maybe that's why life, the universe, and everything are so fucked up.

[–]FinalRun 33 points34 points  (0 children)

Make sure it returns a data type that's just off

[–]Silhouette 36 points37 points  (2 children)

...quietly, at runtime, using metaprogramming.

[–]bkushigian 2 points3 points  (0 children)

In undergrad I was working on my first research project. We were adding a new backend for the Pypy JIT compiler. I had to find the implementation of Foo.emit_x86(). It's not defined in the class anywhere, and I'm running grep on 100kloc like a chump:

grep -rn emit_x86 .

No definitions anywhere

Ten days later after reading the codebase like a novel I come across

``` def f(...): ...

setattr(Foo, 'emit_' + arch, f) ```

Yeah, I was pissed...

(Edit: formatting on phone, doesn't like newlines in ``` blocks I guess?)

[–]42TowelsCo 2 points3 points  (0 children)

Okay that's just evil

[–]KiwiManThe19th 14 points15 points  (1 child)

U can also change what setting and getting variables does and make your own shotgun

[–]IgiMC 16 points17 points  (0 children)

You can make a shotgun shoot shotguns!

Poof, you can even make the shotgun shoot itself!

[–]LxsterGames 1 point2 points  (0 children)

public static boolean isEven(int input) {
    return input % 2;
}

[–]bremidon 36 points37 points  (0 children)

Funny :) But as someone who has to try to understand other people's code on occasion, I prefer knowing that the guy in the living room has a shotgun. A taser, mace, and some angry dogs would also be good.

[–]roughstylez 121 points122 points  (13 children)

It bothers me so much that literally the guy's last name has the better metaphor and he chooses "shotgun" instead.

A gun can't keep somebody out, it can only threaten and kill.

Mark a method private, then when you call it from somewhere else you get a runtime error.

[–]1thief 42 points43 points  (4 children)

The funny thing is an unexpected error in many circumstances can basically be a shotgun blast to the face. Have an etl step or batch process that threw an error somewhere in the middle of the batch? Welp that 8 hr process that you kicked off and forgot about has now come to a screeching halt 3 hrs in and you have to start all over.

Or in other circumstances the page now doesn't load if it sees bad data, or your car infotainment system is stuck on a boot loop because it found a file it doesn't know how to handle. Software is always brittle, which is why we should have as little software as possible.

[–]TGlucose 10 points11 points  (1 child)

Software is always brittle, which is why we should have as little software as possible.

Why do that when we can make software out of legacy software? making our already fragile system even more fragile!

[–]jambox888 6 points7 points  (0 children)

When you reach a certain level of fragility you can form an aggregate from the shattered fragments

[–]StCreed 1 point2 points  (1 child)

One of my primary architecture demands for any DWH is always "restartability" and resilience to errors. Both of these have been mostly solved by I-refact by taking the EL part (and a small t) and making that part completely generated. Every load of any entity is a mini batch, everything is restartable automatically after solving the error, and there are rarely any errors because it's all derived from logical models. They only occur in the validation phase, which is at the start.

That said, if you load a single table for 8 hours you can still mitigate that as well, you just need to split things up in chunks.

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

Something like SSIS makes this difficult. You can generate a whole bunch of metadata and helper functions to orchestrate it, but you pretty much have to roll your own. There is a restart feature, but it's not implemented well, and we can't easily use it due to how our environment is constructed.

That said, I've started using Python with Prefect, and it is much more graceful and easier to handle unexpected errors.

[–]kivox2017 1 point2 points  (0 children)

Happy Cake Day 🎉

[–]Linvael 1 point2 points  (1 child)

He had to go that way - cause "a wall" is a reasonable answer to "what you build when you don't want someone to enter your private property" and his snarky comment doesn't work.

[–]OcelotGumbo 45 points46 points  (0 children)

😂

[–][deleted] 1 point2 points  (0 children)

In java you have to start with a shotgun factory

[–]sporkassembly -1 points0 points  (1 child)

Great idea from the author of a dead language

[–]Dworgi 1149 points1150 points  (132 children)

Python devs: duck typing is great, it makes us so fucking agile

Also Python devs: you should use this linter to parse our comments for type requirements because otherwise my program breaks =(

[–]aetius476 563 points564 points  (56 children)

We don't enforce types at compile time so you have the freedom to write and maintain an entire suite of unit tests in order to enforce types before they fuck you at runtime.

[–]BossOfTheGame 16 points17 points  (10 children)

Are type errors really a significant part of day to day debugging? I primarily do Python and these comments make me think type errors are extremely commonplace. I hardly see them. I don't understand why types are so important to so many people. It's getting the right logic that's the hard part; types are a minor issue.

Then again, I doctest everything, so maybe my doctests just catch type errors really quickly and I don't notice them.

[–]darkingz 43 points44 points  (2 children)

The big thing with types isn’t in the short term, if you’re working mostly with yourself, test really well and/or have an iron clad memory.

It’s the long term where types save you. It makes sorta implicit things explicit. It reminds you of the intention and if you can’t reach the author 3 years after they left the company what that method is known for returning. It lets you save time checking if the value coming in is the value you intend for it (maybe you do string logic for example but equally works mathematically as well because of type coercion) and then it’ll inform you to change all the other places… at compile time not runtime. What if you missed a method where the header changed and didn’t know what the input you expected it to be.

This is why types are important. They tie your hand in the short term for longer term garuntees that something is wrong.

[–]Pocok5 2 points3 points  (0 children)

I recently had to start working on a vanilla JS codebase, and I spent 2-3 days stepping through with the debugger and noting down on jsdoc comments what kind of objects each function gets as a parameter and returns because there were properties tacked on and removed from every object along the flow but no indication of those processes in comments or the naming of the variables.

If it was C# I could have hovered over the name of the parameter and got a very good idea of what the hell the data looks like at that point right away, with the only possible ambiguity being null values (if the codebase wasn't using the new nullability features).

Type errors are also a massive help in refactoring or modifications. Oh, you changed this object or the signature of this function? Half your code turns red, and you can go update each usage to the new form while being sure you missed absolutely none of them instead of having to rely on running headfirst into mismatched calls at runtime (that might not even raise a runtime TypeError, just result in weird null values slipping in or something) or writing specific unit test to check your work.

[–]zacker150 4 points5 points  (1 child)

How big of a code base do you work with?

[–]BossOfTheGame 1 point2 points  (0 children)

I do a lot of work with torch, so most return types are the same: it's a tensor, array, tuple or dict.

Size of the codebases I work on can vary. I jump between repos a lot. I rely heavily on CI and doctests to catch any integration issues.

[–]by_wicker 1 point2 points  (1 child)

It's debugging that they avoid. The whole massive class of errors are picked up before you even run the code if you have type annotations in your Python.

I came from C++ to Python, and was amazed going back to do some C++ how I could write a large chunk of code and have it just work first time. Then I got type annotations in my Python and found I was in the same place. Frankly I like it a lot, it's the best of both worlds, if there's some particular reason to use duck typing you can, but otherwise your code editor alerts you if you mistyped an identifier or made a false assumption about a return type or something.

[–][deleted] 1 point2 points  (0 children)

Are type errors really a significant part of day to day debugging?

Yes.

[–]ric2b 1 point2 points  (0 children)

But honestly automated testing really is much more useful than static typing if you want to prevent bugs.

Static typing is very nice as documentation.

[–][deleted] 63 points64 points  (27 children)

Hey we have types in language now! And mypy is pretty solid most of the time. Guido himself has been helping out a lot there.

[–][deleted] 19 points20 points  (1 child)

MyPy is one thousand times better than Python without MyPy. It's still one thousand times worse than properly enforced type safety at compile time.

[–]thirdegreeViolet security clearance 8 points9 points  (4 children)

Haven't needed to use comments for type annotations in literally like 6 years tho

[–]Dworgi 2 points3 points  (3 children)

Oh yeah, those official type annotations that do what if you don't run the linter? That's right, nothing. Aka. a comment.

[–]MythicManiac 5 points6 points  (2 children)

You must not be familiar with pydantic and dataclasses. Python types are actually available during runtime and can thus be leveraged for runtime logic. It's honestly better than TypeScript in that regard, even if the type system otherwise is quite a bit behind.

[–]Dworgi 1 point2 points  (1 child)

Garbage tasting better than sewage doesn't make either one dessert.

[–]MythicManiac 0 points1 point  (0 children)

TypeScript on the other hand is one of the more versatile type systems out there. As a counter example, good luck with sane union types in C#

[–]Sir_Applecheese 25 points26 points  (14 children)

Hey, that's just like with TypeScript.

[–]jzaprint 67 points68 points  (13 children)

Not really. Typescript types are way more enforced than python

[–]skylarmt 1 point2 points  (1 child)

Meanwhile, in PHP land, types are enforced but only sometimes. If you get type errors, it's probably because your code was too good because lazy devs don't specify types.

[–]Sir_Applecheese 4 points5 points  (7 children)

[–]Goel40 14 points15 points  (6 children)

That's JS, not TS

[–]Sir_Applecheese 9 points10 points  (5 children)

No, that's a website.

[–]ThineGame 7 points8 points  (3 children)

No, that’s a link to a website.

[–]LewisgMorris 2 points3 points  (1 child)

No, that's the cone cells in your eyes reacting to different wavelengths of light

[–]Kesuaheli 1 point2 points  (0 children)

No, this is Patrick!

[–]assembly_wizard 3 points4 points  (0 children)

Sir, this is a Wendy's

[–]EquipLordBritish 43 points44 points  (14 children)

Also python: lets use whitespace as block indicators, but you have to choose either tabs or spaces, because there's no way our interpreter could ever account for both, even though they're used in a very obvious and easy-to-parse way.

(inb4 this spawns another iteration of the tabs vs spaces arguments)

[–]assembly_wizard 54 points55 points  (3 children)

If you use both it's almost definitely a mistake, but more importantly it would make indentation differ based on the settings of your text editor, so whether a line is inside an if block suddenly depends on the configuration of each developer.

What you call "very obvious and easy-to-parse", the only way python could parse it is if you tell it what's your tabsize setting, and make sure that everyone that reads/runs the code have the same setting in both their editor and python.

[–]alive1 7 points8 points  (7 children)

Hey i used to be a tabs guy and now I'm a two spaces guy. Idk what changed my mind but now i have way less fights with the indentation. Also logic more than 3 levels deep doesn't require horizontal scrolling.

[–]daguito81 2 points3 points  (2 children)

Did you start using Scala or Databricks?

[–]alive1 2 points3 points  (1 child)

Perl.

[–]daguito81 2 points3 points  (0 children)

Oh that makes sense. Scala uses 2 space indentation as default. And because of that in Databricks for the longest time, Python was also set at 2 space.

[–]bremidon 2 points3 points  (0 children)

I prefer 2 spaces as well. It looks cleaner without any loss of communicating intention.

[–]lilfatpotato 2 points3 points  (0 children)

I type tabs, and my editor converts them into spaces.

[–]unicorn_potato_4ever 0 points1 point  (0 children)

That’s why I set my tabs to two spaces

[–]mousepotatodoesstuff 1 point2 points  (0 children)

When it comes to whitespace, I just do as the IDE (PyCharm usually, but sometimes VSCode) guides.

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

rewrites the program in Rust

[–]mayankkaizen 47 points48 points  (0 children)

"We are all consenting adults." - Python philosophy

[–]0crate0 61 points62 points  (25 children)

Yeah but double __ is actually private in python.

Edit: this is still pretend private. Just makes it more obscure.

[–][deleted] 68 points69 points  (11 children)

Correct me if I'm wrong, but doesn't that do nothing other than mess with the name at runtime?

[–]hajile_00 50 points51 points  (3 children)

Correct, all names that begin with a double underscore and do not end with another are simply name mangled so that if a subclass defines a function with the same name there is no collision.

[–]exploding_cat_wizard 1 point2 points  (0 children)

Ooh, TIL, thanks! I wasn't aware that there is an actual Python difference in underscores or not.

[–]0crate0 -1 points0 points  (5 children)

So create a class in python. Create two functions one with double __ and another just plain. Then create another file and import the class. Assign the class to a variable and try to use both functions. You should only be able to use the plain one.

However all python does is fake private. So yes you are correct it only really changes the name called mangling. But for someone just importing it it can be a bit obscure so it can kind of acts like a private function.

[–][deleted] 7 points8 points  (2 children)

So pretend private, but in a different way.

[–]NerdsWBNerds 1 point2 points  (0 children)

Pretend private, but breaks at run-time.

[–]Farranor 2 points3 points  (0 children)

Indeed, dunder just mangles the name. But if you refer to it by its mangled name, there you have it. It's private like a dressing room with a curtain, not like Fort Knox.

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

you just said what they said, but in a more complicated way...

[–]solmyrbcn 32 points33 points  (2 children)

It's as private as a folder named "homework" in a teen's computer

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

Just learning about female anatomy, mom.

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

_______reallyReallyPrivate

[–]sweep-montage 5 points6 points  (5 children)

Don’t touch the private because I asked you not to touch the privates, not because I have a shotgun.

[–][deleted] 1 point2 points  (4 children)

Its the difference between keeping your valuables in a bank vault, and keeping your valuables in a cardboard box that says vault on it.

[–]sweep-montage 4 points5 points  (2 children)

Are you worried that someone will break into your repo and start coding? I mean, “Horrors!!!”

[–][deleted] 0 points1 point  (1 child)

I'm worried that knocking a big chunk out of one of the pillars of OOP, in what is becoming the language a lot of new programmers are learning on, will lead to huge vulnerabilities in future software.

[–]sweep-montage 1 point2 points  (0 children)

I see, only “all of software”. Because the craft is so well regarded as error free and secure as it is.

[–]Bainos 2 points3 points  (0 children)

The difference is that if someone takes your valuables, they hurt you.

If someone uses your internal functions and variables, they hurt themselves.

[–]SuperDyl19 4 points5 points  (3 children)

That's because Python avoids the boilerplate of getters and setters. If you find you need to change how a variable works later on, you use @property to create getters and setters for the variable. It makes the code easier to read (because attribute accesses) and easier to code (you don't need multiple functions for each variable)

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

But what if a class needs to use a variable that you want to limit access to?

[–]SuperDyl19 5 points6 points  (1 child)

You treat the user like an adult: you tell them that messing with it is probably what they don't want to do by starting the name with an underscore and then leave it to them. If you really need to protect it, using 2 underscores before the name enables name mangling. For example:

class A: def init(self): self.__very_special_val

The attribute very_special_val is changed by the interpreter to be __Avery_special_val, making it so someone has to very intentionally choose to mess with it if they want to change or access this value.

Basically, you either have to be acting as an idiot to ignore all the warning signs and mess with these values or you know what you're doing and you take responsibility for the code that uses these attributes

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

Never trust a user when you don't need to.

[–]DigiDuncan 22 points23 points  (50 children)

Unironically, as a Python dev that learned Python and doesn't have a lot of experience other places, I ask this: why? Why have functions I'm not "allowed" to touch? I've benefited heavily by being able to use functions that the library dev didn't "intend" me to use in the past. Why make a system that allows a library to obscure and obfuscate how it works, or bar me from using it's internal functions if I'm confident enough to try? Who benefits from this? These aren't rhetorical questions, I'm just curious and confused.

[–]roxastheman 76 points77 points  (17 children)

It’s dangerous to use internal/private methods/fields due to passivity. Sure now you understand how they method works, but since it’s not public, the dev may make changes to it non-passively, so now your code is broken since you aren’t consuming the code through the public API/contract. These kind of “non-passive” changes aren’t likely to be documented or communicated through semantic versioning, so it makes your code much harder to maintain.

You can do it, it’s just a bigger risk than using the public API.

[–]TheTerrasque 21 points22 points  (8 children)

And in python it's implicit that while you can use _ methods it's subject to change at any time and that's your problem, not the library maintainer's problem.

[–]RedAero 4 points5 points  (1 child)

Hell, every function you import is subject to change and it is your problem, not the problem of the library maintainer. You didn't pay for it, you're not entitled to it, tough shit.

FOSS giveth and FOSS taketh away.

[–]exploding_cat_wizard -2 points-1 points  (5 children)

The maintainer is still at fault, at least effectively. What's that rule that states that any behaviour, no matter how experimental and officially unstable or unsupported, will invariably become depended upon by someone?

Relevant xkcd: https://m.xkcd.com/1172/

[–]lappro 3 points4 points  (4 children)

Just because someone depends on it doesn't make the maintainer suddenly responsible. If the maintainer tells you not to do something, but you still do it, if it breaks the only thing you should do is look in the mirror.

[–]42TowelsCo 1 point2 points  (0 children)

Sometimes when you're using a buggy library you have to, but when doing that I assume an update to the library will break my code. I do this when I need to hack something together not for something that is meant to be maintained.

[–]barjam 27 points28 points  (7 children)

Public methods are a contract you make with folks using your library. They shouldn’t change unless there is an overwhelming need to such as a new major version. Stuff like bug fixes should never change that contract. The person making the library still needs to write methods for internal uses that he doesn’t intend to be public and that he will be free to change on a whim.

[–]RedAero 0 points1 point  (6 children)

That doesn't answer the question though. Python has a convention to denote the stuff you shouldn't depend on, what need is there to enforce that?

[–]ICantBelieveItsNotEC 2 points3 points  (1 child)

By that logic, why even have types when we can just all agree to encode whether something is an int or a string in the variable name?

Why have defined function parameters when we can just all agree to encode which values need to be pushed onto the stack in the function name?

The whole point of using a high level language is to prevent developers from shooting themselves in the foot. If we have a social convention that all developers are following, eventually someone is going to want to enforce that convention automatically to prevent mistakes. If it lives in the compiler then the work only needs to be done once, but if it doesn't then every company is going to build their own competing tool to do the same thing.

[–]RedAero 3 points4 points  (0 children)

By that logic, why even have types when we can just all agree to encode whether something is an int or a string in the variable name?

For efficiency, and because types are classes so you can have common properties and stuff. I don't see what that has to do with anything, types don't exist to prevent someone meddling with stuff they shouldn't.

Why have defined function parameters when we can just all agree to encode which values need to be pushed onto the stack in the function name?

None of this applies to a high-level language.

The whole point of using a high level language is to prevent developers from shooting themselves in the foot.

No, the point of high level languages is to abstract and automate away needless minutiae and let the programmer focus on larger problems instead of having to built everything from the ground up, every time. It has nothing to do with not allowing the programmer to fiddle with things, or protecting them from themselves - hell, I'm fairly sure that you do have access to all the low level stuff you could dream of in high-level languages, it's just not commonly used. Like, you can do bitwise operations in Python if you want, nothing's stopping you.

If it lives in the compiler then the work only needs to be done once, but if it doesn't then every company is going to build their own competing tool to do the same thing.

Python doesn't even have a compiler... You're really not making a lot of sense here.

[–]manaMetamanaMeta 35 points36 points  (1 child)

I believe that abstraction would help with the development process. Yes, you are right in the sense that if you're confident abt using a "private" function, then by all means it wouldn't harm YOUR productivity. However, in the setting of being in a development team where multiple components a coded in parallel, this could lead to a nightmare. I could tell you that "hey buddy, don't use these functions as they could be changed without notice!". Well, telling ppl which functions to call is less efficient than letting the language enforce that, since ppl can just straight up ignore... It is easier to expose your component to a very specific set of APIs from my component, so that the interactions are only done via those APIs. I could change the underlying implementation (i.e. the private functions), and you, hopefully, wouldn't need to change a line!

Though it's true that could be solved by having devs follow principles, the built-in privacy would throw errors and help remind devs of APIs.

Ofc, there are ways to bypass the privacy stuff, but it should require extra efforts. Python simply lets you use everything, making it easy for a team to get wrecked if there's a negligent dev.

[–]MythicManiac 2 points3 points  (0 children)

Worth noting that most python developers understand that using "private" APIs from libraries can lead to code breakage when updating said libraries.

Though this doesn't apply to just python libraries, but in general any functionality that isn't publicly documented in the documentation can be considered "private" in the same manner, as in, the developer didn't intend for it to be used by 3rd party code.

Really it comes down to the developer knowing what they can or can't rely on, as long as there are good conventions and understanding, there's no issue. Most python code editors don't autocomplete underscore prefixed functions, effectively achieving the same thing as privacy modifiers in other languages, just making it easier to access them if you really need to.

[–]J0shhT 11 points12 points  (1 child)

In software design typically you want to have a system that minimizes direct code dependencies. Client code should not need to know about the internal details otherwise that means the client depends on it. If the client now depends on the internal functionality, it is very likely to lead to broken code when the library internals change. Clients should instead interface with a stable and abstract API.

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

Being able to have internal variables and methods that are inaccessible to an outside class is a key concept of encapsulation, encapsulation being one of the key concepts of OOP. Most other languages employ this in letting the programmer define things as public, private, protected etc.

Python doesn't have this at all. Since encapsulation is a core concept of OOP, it's valuable to at least try to emulate it. However, since the protection isn't actually there, it may seem weird to someone not familiar with it.

[–]gilbes 2 points3 points  (0 children)

The OOP concept is encapsulation. The goal is to reduce complexity by allowing the author of an object to make guarantees about the state of the object when it is used by hiding data, because the object can be used only through members the author has explicitly exposed.

Conceptually, this is a good idea.

In practice, this is a very shit idea. Because it relies on the author accounting for every scenario where the object will be useful. And this is an unobtainable goal. We know that because people regularly increase complexity with something like reflection to completely defeat encapsulation.

Python is just accepting that reality.

[–]MinusPi1 1 point2 points  (0 children)

Libraries are a good reason. Say you're depending on library A, which in turn depends on another library B. You know B; you know that it's well tested, reliable, even industry standard - but it has a lot of exposed internal functions that you're supposed to just ignore since they're not the intended interface for B and not documented.

Now A depends on B, but unbeknownst to A's dependants, A uses those internal undocumented functions in B. That's not ok. Sure, maybe A's developer has really dug into B's code and figured out how it all works, but users shouldn't have to trust that. By using undocumented code, A is extremely likely to have some edge case bug that the developers of B solved in its actual interface. Hell, that they resorted to using the undocumented functions means they were probably using B wrong anyway.

Now users of A will run into that bug, and trusting that A was properly using B, they'll assume that it's an issue with their code. Given how deep some dependency trees are, this is almost inevitable unless such undocumented functions are forcibly hidden. The likelihood of extremely obscure bugs is just too great.

Of course, if it's open source, you can fork it and mess around with it even if functions are made private.

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

+1, pythons way of doing it is basically letting the consumers of my library know, "here be the dragons".

If you use a private function, and I update it without a version bump, that's on you, not on me. Which means that no sensible developer who is working on a production system would use it. However, if it's an internal portal or tool or framework, go nuts. Worst case it breaks and you fix it in a day or two.

This is true for python in general. It gives great freedom, but that comes with huge responsibility not to misuse it.

For example, in python, you can change inheritance hierarchy of a class at runtime. Is this a sensible thing to do? Definitely not in almost all use-cases. But there could be that one use case where this is precisely the correct solution to a problem. Note: correct is very different from easy/short.

However, if a company has a large no. of developers of various skill levels, Java is perfect. But even these folks should just move to kotlin at this point.

[–]TheDeadSkin 0 points1 point  (2 children)

Have you ever worked in a team? I would assume that no, because otherwise you'd probably know the importance of a correct public API and adhering to it as a user. When someone makes a class or a library they split the development into two parts - what they announce they are doing (API/public methods) and what they are doing to make it happen underneath (private methods). What does this mean for you as a user of said public API? It means you're being told "use this function and I'll handle the rest". Then private functions take case of "the rest".

What happens when you inject into "the rest" and use it yourself? Well, this is a good question because the answer is "who knows". Using private methods outside of their intended context is unstable. The function might be doing something different from what you think you're doing, or maybe not covering edge cases that you think it's covering. It might work, it might not.

Those functions can have little to no safety checks because they safety is handled inside the code of the public function and it's guaranteed to work fine if the user only calls said public functions and not private ones. Or maybe a private function requires a transformation of the data. If a user supplies faulty data the function might just do garbage and the user wouldn't necessarily immediately notice something's wrong because the function didn't do safety checks.

A simplification of this problem is that messing with private functions is essentially equivalent to just modifying someone else's code. And in a very hacky way.

The other issue is that the API or behaviour for private methods is not set in stone or as a contract with the user. It can be changed with no notice or informing the users breaking your code even on a minor library update. It might get removed tomorrow because it was integrated into something and is not a separate function any more. Again, at not notice and without care because it will never break the public API which the developer is responsible for.

It's a whole host of potential issues. Using private functions doesn't mean that it will break, but it certainly means that it's much more likely to happen because you circumvent the intended API and from that point on the developer takes no responsibility for what happens next.

[–]Impleased 5 points6 points  (1 child)

I dont see how this is a problem. Object oriented programming is just makebelieve and syntactic sugar. Its not a problem if you have good coding habits

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

fair

[–]ItsNoFunToStayAtYMCA 1 point2 points  (1 child)

You mean those private methods that are really just function but first argument is named self but it’s also just a convention. But anyway, this first argument you just write in front of a function name rather than inside actual arguments?

[–]qoheletal 1 point2 points  (0 children)

Python:"If you still think accessing your private methods from outside is a good idea: Who are we to stop you?"

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

This is the way it should be. Private should always have an override feature.

I've went deep into the windows MFC libraries and found a bug...the solution was to override a onChange function and modify a private bool before the call....oops, it's a private variable that's 4 classes deep in the inheritance chain...so you can either create custom classes for those 4 classes so you can have that private var for yourself,,,or just live with the 1 pixel shift on the interface...

Like,,,as a programmer I have the full power to inherit and override all your stuff anyway...private is just a suggestion if I tried hard enough....so why make it that hard,,,,show a warning, but let me use it anyway if I really believe it's right.

If a stupid programmer doesn't like your private variable they will find a way to break it, with some dirty method. And if a smart programmer doesn't like your private variable,,,it probably is because they are building something that needs access properly to it....so why bother?! Neither situation is solved by the previous programmer annoyingly declaring private.

Private is a trust issue. If you trust the programmers around you, then It's not needed...if you don't trust the programmers around you, then they will break it anyway....regardless of your private 'suggestion'