Data Hiding in Python Class

后端 未结 4 1371
半阙折子戏
半阙折子戏 2021-01-02 09:07

I know that the attributes of class which are declared by double underscore __ prefix may or may not visible outside the class definition. As we can still acces

4条回答
  •  刺人心
    刺人心 (楼主)
    2021-01-02 09:56

    While the accepted answer by unutbu looks like a good idea to hide data, the private dictionary still accessible using __closure__ (this attribute cannot be removed):

    def make_A():
        private = {}
        class A:
            def __init__(self):
                self.catch = 100
                private[self,'a'] = 1    # you can modify the private data
                private[self,'b'] = 2    
                private[self,'z'] = 26    
            def foo(self):
                print(private[self,'a']) # you can access the private data
        return A
    
    
    A = make_A()
    a = A()
    a.foo()  # 1
    a.foo.__closure__[0].cell_contents[(a, 'a')] = 42
    a.foo()  # 42
    

    Or following the link provided by Sumukh Barve in the comments:

    def createBankAccount():
        private = {'balance': 0.0}
        def incr(delta):
            private['balance'] += delta;
        account = {
            'deposit': lambda amount: incr(amount),
            'withdraw': lambda amount: incr(-amount),
            'transferTo': lambda otherAccount, amount: (
                account['withdraw'](amount),
                otherAccount['deposit'](amount)
            ),
            'transferFrom': lambda otherAccount, amount: (
                otherAccount['transferTo'](account, amount)
            ),
            'getBalance': lambda : private['balance']
        }
        return account;
    
    
    account = createBankAccount()
    
    print(account['getBalance']())
    account['getBalance'].__closure__[0].cell_contents['balance'] = 1000**1000
    print(account['getBalance']())  # I can buy a couple of nations
    

    I bevile the only way to create private attributes is to write some kind of CPython extension.

提交回复
热议问题