Как я могу объявить функцию класса Python, которая будет использоваться только другой функцией того же класса? - PullRequest
0 голосов
/ 16 октября 2019

Допустим, у меня есть следующий класс:

class A():
    def fn1(self):
        pass
    def fn2(self):
        pass

Теперь я хотел бы вызвать функцию fn3 внутри fn1 и fn2. Функция fn3 должна быть такой, чтобы ее могли вызывать только fn1 и fn2 (поскольку fn3 потребуется только для fn1 или fn2).

Мой подход был бы таким:

class A():
    def fn3(self):
        pass
    def fn1(self):
        fn3()
        pass
    def fn2(self):
        fn3()
        pass

Здесь я вижу недостаток в том, что fn3 должен иметь аргумент self (в моем случае fn3 не использует его). Еще один недостаток: fn3 может вызываться другими объектами, объявленными вне класса, что не является обязательным.

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

Наиболее близкая вещь, которую вы найдете в Python к "приватному" методу - это объявить его с двумя подчеркиваниями __. В вашем случае:

class A():
    def fn1(self):
        pass
    def fn2(self):
        pass
    def __fn3(self):
        pass

Часть self в __fn3 просто "привязывает" метод к классу. Вам не нужно использовать его в теле метода.

В зависимости от сложности fn3, другим решением является создание лямбды и передача ее другим функциям:

__fn3 = lambda self: print("New private bound")

class A():
    def fn1(self, myfunc):
        pass
    def fn2(self, myfunc):
        pass

a = A()
a.fn1(__fn3)
0 голосов
/ 16 октября 2019

@ jonrsharpe правильно. Python считается «языком программирования для взрослых» - в том смысле, что у него нет механизма, препятствующего программисту делать то, что вы от него не хотите. Добавляя двойное подчеркивание __methodName, вы говорите другим программистам: «Не называйте это внешне». Но если они захотят, они будут: D

Если вы действительно хотите стать педантичным, вы можете сделать что-то похожее на здесь и проверить метод вызова, чтобы убедиться, что он «авторизован»вызывающий метод.

Т.е.

import inspect

class A():
    def fn1(self):
        curframe = inspect.currentframe()
        calframe = inspect.getouterframes(curframe, 2)
        if "fn3" == calframe[1][3]:
            print("This is fn1")
        else: 
            print("NO NO! Bad function '{}'".format(calframe[1][3]))

    def fn2(self):
        curframe = inspect.currentframe()
        calframe = inspect.getouterframes(curframe, 2)
        if "fn3" == calframe[1][3]:
            print("This is fn2")
        else: 
            print("NO NO! Bad function '{}'".format(calframe[1][3]))

    def fn3(self):
        self.fn1()
        print("This is fn3")

    def notfn3(self):
        self.fn1()
        print("This is notfn3")

if __name__ == '__main__':
    o = A()
    o.fn3()
    o.notfn3()

ВЫХОД:

This is fn1
This is fn3
NO NO! Bad function 'notfn3'
This is notfn3

Но (ИМХО), это много кода и много дополнительныхобработка, просто чтобы заставить кого-то не делать то, что вы не хотите, чтобы он делал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...