python--面向对象与模块补充,反射

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python--面向对象与模块补充,反射相关的知识,希望对你有一定的参考价值。

在python中,私有属性可以通过__(两个下划线定),实际上一个下划线也表示私有属性,不过还是可以访问到

关于私有属性、方法——Python并没有真正的私有化支持,但可用下划线得到伪私有,所以尽量避免定义以下划线开头的变量

"单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问;不能用'from module import *'导入,类似于php的protected受保护的,直接通过实例化对象和子类都可以访问

class People(object):

_test1 = "一个下划线的私有属性"

__test = '两个下划线的私有属性'

def __init__(self,name):

self.name = name

def run(self):

print("%s is running" %self.name)

p = People("Jack")

p.run()

print(p._test1)

技术分享图片

技术分享图片

" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

class People(object):

_test1 = "一个下划线的私有属性"

__test = '两个下划线的私有属性'

def __init__(self,name):

self.name = name

def run(self):

print("%s is running" %self.name)

p = People("Jack")

p.run()

print(p._test1)

print(p.__test)

print(People.__test)


技术分享图片

技术分享图片

类名也是不能直接访问的: 

技术分享图片

技术分享图片

其实这只是表象通过__dict__查看所以属性

print(People.__dict__)


技术分享图片

其实python重新对双下划线的私有变量重新定义了,所以通过重新定义的名字可以直接访问即通过_类名__属性名访问

print(p._People__test)


技术分享图片

可以直接访问

私有方法的访问:


技术分享图片

技术分享图片

正常是通过类内部提供的方法访问 

技术分享图片

技术分享图片

私有的属性,不能通过对象直接访问,但是可以通过方法访问

私有的方法,不能通过对象直接访问

私有的属性、方法,不会被子类继承,也不能被访问

一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用

可以通过调用继承的父类的共有方法,间接的访问父类的私有方法、属性

对于封装,类本身就是一种封装,定义私有属性方法也属于一种封装,还有一种就是内部实现的逻辑,外部无法访问,只听提供一个接口供外调用。

反射:

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)


技术分享图片

技术分享图片

技术分享图片

执行:

m()


技术分享图片

设置属性

#设置属性

setattr(p,'school',"qinghua")#等于p.school='qinghua'

print(p.school)


技术分享图片

技术分享图片

#修改也可以

setattr(p,'name',"lucy")

print(p.name)

技术分享图片

技术分享图片

删除:

setattr(p,'name',"lucy")

print(p.name)

delattr(p,"school")

delattr(p,"schools")#删除不存在的会报错

#print(p.school)


技术分享图片

技术分享图片

技术分享图片

技术分享图片

反射可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,意思是可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能,

导入其他模块,利用反射查找该模块是否存在某个方法

A文件。im2.py

class A():

#'A先定义,但是还没有实现具体的功能'

def __init__(self,addr):

print('定义好接口未实现')

self.addr=addr

B文件。demo.py

from im2 import A

a = A("china")

if hasattr(a,'get'):

func_get=getattr(a,'get')

func_get()

else:

print('---->不存在此方法')

print('处理其他的逻辑')


技术分享图片

技术分享图片

print("im2文件")

def test():

print("test")

def test1():

print("test1")

module_test = __import__('demo.im2')#获取文件名

print(module_test)


技术分享图片

技术分享图片

可以看出导入后会执行导入的文件

module_test = __import__('im2')

print(module_test)

module_test.test()#直接调用,如果是文件夹要写上包的名字例如im2.py在demo文件夹下,module_test.im2.test()


技术分享图片

技术分享图片

模块在导入的时候如果使用了,from module import * 那么私有方法不能被导入 

技术分享图片

技术分享图片

技术分享图片

会报错

如果改为直接调用可以运行,这说明python没有绝对的私有机制


技术分享图片

技术分享图片

双下划线也一样 

技术分享图片

技术分享图片

技术分享图片

以上是关于python--面向对象与模块补充,反射的主要内容,如果未能解决你的问题,请参考以下文章

learn_Day14 内置函数补充反射初识面向对象

python模块补充面向对象

Python面向对象之反射

面向对象基础 反射

面向对象基础 反射

Python系列之反射面向对象