Python 面向对象编程(进阶II)

 

类成员的修饰符

对于每一个类的成员而言都有两种形式:

  • 公有成员,在任何地方都能访问
  • 私有成员,只有在类的内部才能方法。私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)

私有成员和公有成员的访问限制不同

静态字段

  • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
  • 私有静态字段:仅类内部可以访问;
class C:
    name_public = "pubic static"
    
    def func(self):
        print(C.name_public) # 类内部可以访问

class D(C):
    def show(self):
        print(C.name_public)  # 派生类中可以访问

print(C.name_public)    # 类访问

obj = C()
obj.func()     
obj_son = D()
obj_son.show() 
class C:
    __name_private = "private static"
    
    def func(self):
        print(C.__name_private)

class D(C):
    def show(self):
        print(C.__name_private)

print(C.__name_private)     # 类不可以访问

obj = C()
obj.func()     # 类内部可以访问

obj_son = D()
obj_son.show() # 派生类不可以访问

普通字段

  • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
  • 私有普通字段:仅类内部可以访问;

ps:如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。

class C:
    def __init__(self):
        self.name_public = "public ordinary"

    def func(self):
        print(self.name_public) #类内部访问

class D(C):
    def show(self):
        print(self.name_public) #派生类中访问

obj = C()

print(obj.name_public)     # 通过对象访问
obj.func()  

obj_son = D()
obj_son.show() 
#!/usr/bin/env python
class C:
    def __init__(self):
        self.__name_private = "private ordinary"

    def func(self):
        print(self.__name_private) #类内部可以访问

class D(C):
    def show(self):
        print(self.__name_private) #派生类中不可以访问

obj = C()

print(obj.__name_private)     # 通过对象不可以访问
obj.func() 

obj_son = D()
obj_son.show()  

方法、属性的访问于上述方式相似,即:私有成员只能在类内部使用

ps:非要访问私有属性的话,可以通过 对象._类__属性名

 

类的特殊成员

1. __doc__ 表示类的描述信息

2. __module__ 和  __class__ 

  __module__ 表示当前操作的对象在那个模块

  __class__     表示当前操作的对象的类是什么

class Foo:
    """ description """

    def func(self):
        pass

print(Foo.__doc__)

  obj=Foo()
  print(obj.__module__)
  print(obj.__class__)


执行结果:
description
__main__
<class '__main__.Foo'>

3. __init__ 构造方法,通过类创建对象时,自动触发执行。

4. __del__ 析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

5. __call__   对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):
        print('__call__')

obj = Foo() # 执行 __init__
obj()       # 执行 __call__

6. __dict__  获取类或对象中的所有成员,以字典的形式返回 {成员名:值,}

7. __str__ 如果一个类中定义了__str__方法,那么在打印对象 时,默认输出该方法的返回值。

class Foo:
    def __str__(self):
        return '__str__'

obj = Foo()
print(obj)

8、__getitem__、__setitem__、__delitem__  用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):
    def __getitem__(self, key):
        print('__getitem__',key)

    def __setitem__(self, key, value):
        print('__setitem__',key,value)

    def __delitem__(self, key):
        print('__delitem__',key)

obj = Foo()
obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'v2'   # 自动触发执行 __setitem__
del obj['k1']           # 自动触发执行 __delitem__

 

9. __iter__   用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__ 

class Foo(object):
    def __init__(self, sq):
        self.sq = sq

    def __iter__(self):
        return iter(self.sq)

obj = Foo([11,22,33,44])

for i in obj:
    print(i)

等同于

obj = iter([11,22,33,44])
for i in obj:
  print(i)

 

类由 type 类实例化产生

class Foo(object):
    def __init__(self):
        pass

obj = Foo()

print(type(obj))
print(type(Foo))

执行结果:
<class '__main__.Foo'>
<class 'type'>

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

obj对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:类 是由 type 类实例化产生

 

反射

反射是通过字符串的形式操作对象相关的成员

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

import sys
class WebServer(object):
    def __init__(self,host,port):
        self.host=host
        self.port=port 

    def start(self):
        print('Server is starting')
    def stop(self):
        print('Server is stopping')
    def restart(self):
        self.stop()
        self.start()

def test(ins,name):
    print('runing...',name,ins.host)

if __name__ == '__main__':
    server=WebServer('localhost',333)
    if hasattr(server,sys.argv[1]):
        func=getattr(server,sys.argv[1])
        func()

    setattr(server,'run',test) ## server.run=test
    server.run(server,'Bob')
       
    delattr(server,'host')
    server.restart()
    delattr(WebServer,'start')
    server.restart()

执行结果:

Server is starting
runing... Bob localhost
Server is stopping
Server is starting
Server is stopping

AttributeError: 'WebServer' object has no attribute 'start'

 

posted @ 2017-08-13 17:06  bobo0609  Views(173)  Comments(0Edit  收藏  举报