2

I have a class A that need to implement a method meth(). Now, I don't want this method to be called by the end-user of my package. Thus, I have to make this method private (i.e. _meth(). I know that it's not really, private, but conventions matter.)

The problem though is that I have yet another class B in my package that has to call that method _meth(). Problem is that I now get the warning method that say that B tries to access a protected method of a class. Thus, I have to make the method public, i.e. without the leading underscore. This contradicts my intentions.

What is the most pythonic way to solve this dilemma?


  • I know I can re-implement that method outside of A, but it will lead to code duplication and, as meth() uses private attributes of A, will lead to the same problem.

  • Inheriting from a single metaclass is not an option as those classes have entirely different purposes and that will be contributing towards a ghastly mess.

  • is it possible to create or pass object of class A to class B ? – Mahesh Karia Nov 13 '17 at 09:02
  • 2
    Maybe you get a warning in the editor, but you can call the method anyway. – Matthias Nov 13 '17 at 09:02
  • @DeepSpace I thought about it, but then the end-user will be able to call that public wrapper itself. – Anton Bohdanov Nov 13 '17 at 09:08
  • You can't, and this contradiction is even apparent in the topic of your question: "Python **private** method for **public** usage" – DeepSpace Nov 13 '17 at 09:09
  • 1
    @Matthias Sure I do, but I want my scripts as close to PEP as possible, and to not show any warnings. – Anton Bohdanov Nov 13 '17 at 09:09
  • @MaheshKaria yes I can, but to what avail? – Anton Bohdanov Nov 13 '17 at 09:10
  • Have you tried using classmethod?? – Abhijeetk431 Nov 13 '17 at 09:16
  • Then it is not private, but kind of "don't call it unless you know exactly what you are doing". There is a tiny hint regarding naming conventions in PEP8 - people tend to have some expectations based on names. So give it a long name. – VPfB Nov 13 '17 at 09:16
  • If the real question is "How to disable that warning in my IDE?" you should probably tell us which IDE you are using and tag the question accordingly. – tobias_k Nov 13 '17 at 09:18
  • @Abhijeetk431 what for would I use a classmethod? – Anton Bohdanov Nov 13 '17 at 09:22
  • 1
    @VPfB Yes, but that still will be unpythonic - a public method that's not intended to be called. – Anton Bohdanov Nov 13 '17 at 09:22
  • 1
    @tobias_k no, the question is how to do it in the pythonic way, not how to disable the IDE warning. – Anton Bohdanov Nov 13 '17 at 09:30
  • @AntonBohdanov Well, I guess the pythonic way _is_ to ignore the warning... see Bruno's answer. – tobias_k Nov 13 '17 at 09:39
  • @tobias_k the "pythonic way" here is to _explicitely_ silence _this_ exact occurence of the warning. – bruno desthuilliers Nov 13 '17 at 09:52
  • @brunodesthuilliers or not allow this situation to occur in the first place. This whole problem sounds to me like a bad case of someone writing Java using Python's syntax. – jkm Nov 13 '17 at 09:56
  • @jkm the OP made clear the method he is talking about is not supposed to be exposed as part of the public API (which is perfectly legitimate whatever the language), so using a `_protected` name is the obvious pythonic way. I would do the very same thing and I don't think anyone could qualify my code as "javaish" ;) – bruno desthuilliers Nov 13 '17 at 10:02

2 Answers2

2

The fact that pylint/your editor/whatever external tool gives you a warning doesn't prevent code execution. I don't know about your editor but pylint warnings can be disabled on a case-by-case basis using special comments (nb: "case by case" meaning: "do not warn me for this line or block", not "totally disable this warning").

And it's perfectly ok for your own code to access protected attributes and methods in the same package - the "_protected" naming convention does not mean "None shall pass", just "are you sure you understand what you're doing and willing to take responsability if you break something ?". Since you're the author/maintainer of the package and those are intra-package access you are obviously entitled to take this responsability ;)

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • I do know that, but I still want to resolve that conflict so that the right tab of my editor show the tick of success, and not a violet warning symbol. – Anton Bohdanov Nov 13 '17 at 09:13
  • @AntonBohdanov then you'll have to find out which linter your editor uses so you can tell him that you do know what you are doing. – bruno desthuilliers Nov 13 '17 at 09:16
  • I would still like to solve the problem and not just disable the warning – Anton Bohdanov Nov 13 '17 at 09:36
  • @AntonBohdanov this is actually NOT a problem - the code accessing the protected method lives in the same package, you _do_ know what you are doing here, it's OK. The "`_protected`" naming convention does not mean "None shall pass", just "are you sure you understand what you're doing and willing to take responsability if you break something ?". And unless your editor's linter is totally braindead, you should be able to silence the warning _only_ for this exact line. – bruno desthuilliers Nov 13 '17 at 09:49
  • Thanks for this clarification. I think you should edit your initial answer to reflect this comment. Then I think it's the solution I was looking for. I'll make this answer accepted then. – Anton Bohdanov Nov 13 '17 at 11:32
  • A slight problem with this approach though is that developers use different IDEs which require different suppression techniques (think PyCharm and Pylint). If the code is open sourced, the line might be bugging lots of other people even if the original developer is happy with it. – Danylo Mysak Dec 27 '21 at 08:33
  • @DanyloMysak the fact that some tools are possibly a bit too narrow-minded doesn't mean the problem is with the code. – bruno desthuilliers Jan 16 '22 at 10:51
0

The "most pythonic way" would be to not care about private and protected, as these concepts do not exist in Python. Everything is public. Adding a underscore in the name does not make it private, it just indicates the method is for internal use in the class (not to prevent usage by some end-user).

If you need to use the method from another class (without instantiating), it shows that you're not using classes and objects correctly, and you probably come from a different language like Java where classes are used to group methods together in some namespace.

Just move the function to the module level (outside the class), as you're not using the object (self) anyway.

Alex
  • 5,759
  • 1
  • 32
  • 47