2

for example i have myClassFile.py file with code as follow:

class myClass:

    def first(self):
        return 'tea'

    def second(self):
        print(f'drink {self.first()}')

then i have run.py file with code as follow:

from myClassFile import myClass

class_ = myClass()
class_.second()

which when i run will output

>>> 'drink tea'

how to prevent someone to write below code on run.py file or outside myClass ?

class_.first()

so that if they used that method outside myClass class it will be an error or some sort

Hanzcerb
  • 51
  • 6
  • 1
    You can't. You *should* name the function `_first` to indicate that it's not part of the public interface, but there's really nothing you can do to *enforce* that decision. – chepner Jan 10 '22 at 17:24
  • 1
    We're all consenting adults in Python. – Paul M. Jan 10 '22 at 17:24

2 Answers2

3

You can add a level of protection around methods and attributes by prefixing them with __.

But you can't make them totally private (as far as I know), there's always a way around, as shown in example below.

class MyClass:
    def __init__(self):
        self.__a = 1

    def __method(self):
        return 2


obj = MyClass()

# obj.__a  # raise an exception
# obj.__method() # raise an exception
print(dir(obj)) # you can see the method and attributes have been renamed !
print(obj._MyClass__a) # 1
print(obj._MyClass__method()) # 2
qkzk
  • 185
  • 1
  • 6
  • 2
    Also, double-underscore name-mangling really isn't an access modifier, it's sole purpose is to prevent *accidental* name collisions in subclasses. Idiomatically, one would use a single-underscore here -- privacy by *convention* – juanpa.arrivillaga Jan 10 '22 at 17:32
  • @juanpa.arrivillaga indeed that was not dunder methods / attributes. Thank you. – qkzk Jan 11 '22 at 19:18
-1

Python does not have support for these. You can mark them private by prefixing them with _, or make it harder to call them by prefixing them with __.

These are called private methods. To make a private variable or a method in python, just prefix it with a __, so def second(self) turns into def __second(self).

This also works for variables and functional programming variables!

class Test:  
    def test(self):
        self.__test()
        
    def __test(self):  
        print('_test')
        
        
x = Test()
x.__test()

gives an error, but x.test() prints _test out successfully!

Note, this can still be run by using x.__Test__test()

Berlm
  • 447
  • 3
  • 7