Python中的私有方法

fre*_*ude 15 python oop static-methods

我想在我的班级中有一个函数,我将只在这个类的方法中使用它.我不会在这些方法的实现之外调用它.在C++中,我将使用在类的私有部分中声明的方法.在python中实现这样一个函数的最佳方法是什么?我想在这种情况下使用静态装饰器.我可以使用没有任何装饰器和self单词的函数

Ash*_*ary 28

Python没有私有方法或属性的概念,而是关于如何实现类的.但是你可以使用伪私有变量(名称修改),任何前面__带有(两个下划线)的变量都会变成伪私有变量.

来自文档:

由于类私有成员有一个有效的用例(即为了避免名称与子类定义的名称冲突),因此对这种称为名称修改的机制的支持有限.表单的任何标识符__spam(至少两个前导下划线,最多一个尾随下划线)在文本上替换为 _classname__spam,其中classname是当前类名称,其中前导下划线被剥离.只要它出现在类的定义中,就可以在不考虑标识符的句法位置的情况下完成这种修改.

class A:
    def __private(self):
       pass
Run Code Online (Sandbox Code Playgroud)

所以__private现在真的变成了_A__private

静态方法的例子:

>>> class A:
...     @staticmethod         #not required in py3.x
...     def __private():
...         print 'hello'
...         
>>> A._A__private()
hello
Run Code Online (Sandbox Code Playgroud)

  • `__`的目标是避免与子类发生冲突.它通过名称修改来实现,将类名合并到变量中.这使得变量难以查找和访问的事实是副作用. (3认同)
  • 你确实需要装饰师.Python特别处理类方法的第一个参数,所以除非你应用`@ staticmethod`或类似的装饰器,否则你会收到错误. (2认同)

cir*_*cld 7

这里有很多很棒的东西,可以使用前导下划线进行混淆。就我个人而言,我从将所有内容公开的语言设计决策中受益匪浅,因为它减少了理解和使用新模块所需的时间。

但是,如果您决定实现私有属性/方法并且愿意不使用 Python,那么您可以执行以下操作:

from pprint import pprint


# CamelCase because it 'acts' like a class
def SneakyCounter():

    class SneakyCounterInternal(object):

        def __init__(self):
            self.counter = 0

        def add_two(self):
            self.increment()
            self.increment()

        def increment(self):
            self.counter += 1

        def reset(self):
            print 'count prior to reset: {}'.format(self.counter)
            self.counter = 0

    sneaky_counter = SneakyCounterInternal()

    class SneakyCounterExternal(object):

        def add_two(self):
            sneaky_counter.add_two()

        def reset(self):
            sneaky_counter.reset()

    return SneakyCounterExternal()


# counter attribute is not accessible from out here
sneaky_counter = SneakyCounter()

sneaky_counter.add_two()
sneaky_counter.add_two()
sneaky_counter.reset()

# `increment` and `counter` not exposed (AFAIK)
pprint(dir(sneaky_counter))
Run Code Online (Sandbox Code Playgroud)

很难想象您会想要这样做,但这是可能的。

  • 不错的技巧)这是一个如何不使用 python 的好例子,但非常有教育意义) (7认同)

Sil*_*Ray 6

Python没有像许多其他语言那样的"私有"概念.它建立在同意的成人原则之上,该原则表明您的代码的用户将负责任地使用它.按照惯例,以单引号或双引号下划线开头的属性将被视为内部实现的一部分,但它们实际上并未对用户隐藏.双下划线将导致属性名称的名称重写.

另外,我会为你注意到,这self只是按惯例而言是特殊的,而不是语言的任何特征.例如,当作为实例的成员调用它们时,它们隐式地将实例作为第一个参数传递,但是在方法本身的实现中,该参数在技术上可以被命名为您想要的任意事物. self只是易于理解代码的惯例.因此,self除了使隐式实例参数分配给签名中的下一个变量名之外,不包括在方法的签名中没有实际的功能效果.这当然是类方法的不同之处,它接收类对象本身的实例作为隐式的第一个参数,而静态方法则根本不接收隐式参数.


Joh*_*ooy 5

Python 只是不做私有的。如果您愿意,可以遵循约定并在名称前添加一个下划线,但这取决于其他编码人员以绅士风度 \xe2\x80\xa0 的方式尊重这一点

\n\n

\xe2\x80\xa0 或 淑女风格

\n