📜  Python中的面向对象编程2(数据隐藏和对象打印)

📅  最后修改于: 2020-04-07 07:55:32             🧑  作者: Mango

先决条件:Python中的面向对象编程 1(类,对象和成员)

资料属性

在Python中,我们在属性名称前使用双下划线(或__),并且这些属性在外部不会直接可见。

class MyClass:
    # 隐藏MyClass的属性
    __hiddenVariable = 0
    #  一个成员方法,改变__hiddenVariable
    def add(self, increment):
        self.__hiddenVariable += increment
        print (self.__hiddenVariable)
# 测试代码
myObject = MyClass()
myObject.add(2)
myObject.add(5)
# 如下报错
print (myObject.__hiddenVariable)

输出:

2
7
Traceback (most recent call last):
  File "filename.py", line 13, in
    print (myObject.__hiddenVariable)
AttributeError: MyClass instance has
no attribute '__hiddenVariable'

在上面的程序中,我们尝试使用对象访问类外部的隐藏变量,并且引发了异常。
我们可以通过非常有技巧的语法访问hidden属性的值:

# Python程序,展示隐藏成员可以被访问外部类访问
class MyClass:
    # 隐藏成员MyClass
    __hiddenVariable = 10
# 测试代码
myObject = MyClass()
print(myObject._MyClass__hiddenVariable)

输出:

10

私有方法可以在其类之外访问,只是不容易访问。Python中没有什么是真正私有的。在内部,私有方法和属性的名称会被即时修改,以使它们无法通过其给定名称来访问[请参阅源]。

打印对象

打印对象会向我们提供有关正在使用的对象的信息。在C++中,我们可以通过为该类添加一个友好的ostream&运算符<<(ostream&,const Foobar&)方法来实现。在Java中,我们使用toString()方法。在Python中,可以通过使用__repr__或__str__方法来实现。

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return "Test 中 a:%s b:%s" % (self.a, self.b)
    def __str__(self):
        return "str的方法,来自Test: a 是 %s," \
              "b 是 %s" % (self.a, self.b)
# 测试代码
t = Test(1234, 5678)
print(t) # 将会调用 __str__()
print([t]) # 将会调用 __repr__()

输出:

str的方法,来自Test: a 是 1234,b 是 5678
[Test 中 a:1234 b:5678]

有关打印的要点:

  • 如果未定义__str__方法,则print t(或print str(t))使用__repr__
    class Test:
        def __init__(self, a, b):
            self.a = a
            self.b = b
        def __repr__(self):
            return "Test 中 a:%s b:%s" % (self.a, self.b)
    # 测试代码
    t = Test(1234, 5678)
    print(t)

    输出:

    Test 中 a:1234 b:5678

    如果未定义__repr__方法,则使用默认值。

    class Test:
        def __init__(self, a, b):
            self.a = a
            self.b = b
    # 测试代码
    t = Test(1234, 5678)
    print(t)

    输出:

    <__main__.Test instance at 0x7fa079da6710>