文章参考:(15条消息) python中类方法,静态方法,成员函数_xiaoji_electric的博客-CSDN博客_python 静态成员方法
(15条消息) Python中单下划线和双下划线_dishan4749253的博客-CSDN博客
双下划线
(1) 双下划线开头和结尾,如__init__()
Python中存在一些特殊的方法,有些方法以双下划线 “__” 开头和结尾,它们是Python的魔法函数,比如__init__()
和__str__
等等。不用要这种方式命名自己的变量或者函数,但可以重写此类函数,如:
class text:
def __init__(self, message):
self.message = message
def __str__(self):
print("重写的str方法")
m1 = text(message="hello world")
print(m1.message)
m1.__init__("hello")
print(m1.message)
m1.__str__()
输出结果:
hello world
hello
重写的str方法
(2) 双下划线开头:私有属性和私有方法
在前面加上“__”,定义的属性是私有属性,我们不能直接访问。比如 “__xxx” 如果要访问得通过 _class__xxx 的方式进行访问。虽然不能防止修改私有属性,但可以有效降低有意或者无意的修改。
class A:
#私有的类变量
__age = 12
def __init__(self):
# 私有的成员变量
self.__name = "text"
def get_age(self):
return self.__age #这里通过实例访问了类变量
a = A()
#print(a.__name) # 报错
#print(A.__age) # 报错
age = a.get_age()
print(age)
print(a._A__name) # 输出text
输出为:
12
text
同理,可得私有方法:
# 本例演示私有方法
class PriFun(object):
def public(self):
print("这是一个公有方法\n")
# 在内部可以调用私有方法
self.__pri()
def __pri(self):
print("这是一个私有方法\n")
if __name__ == "__main__":
p = PriFun()
# 调用普通实例方法,进而在实例内部调用私有方法,可行
p.public()
# 直接在外部调用私有方法,不可行
p.__pri()
单下划线
_xxx:一种约定,用来指定变量私有。程序员用来指定私有变量的一种方式。不能用from module import * 导入,其他方面和公有一样访问。
# A.py
class A:
def __init__(self):
self.text = "A"
class _B:
def __init__(self):
self.text = "B
# test.py
from A import *
a = A()
print(a.__dict__)
b = _B()
print(b.__dict__)
可以看到我们导入了A.py中所有的类,但其实_B并没有被导入,但是我们可以通过别的方式访问这个类,修改我们的test.py文件为以下内容。
import A
a = A.A()
print(a.__dict__)
b = A._B()
print(b.__dict__)
除了不能通过 from module import * 这种方式导入外,跟公有类并没有差别.
变量
(1) 类变量
类变量定义在类的定义之后,实例变量则是以为self.开头
下面举个例子:
class MtInstall:
ENVS = {'物理机':PM_T,'虚拟机':VM_T}
KEYS = ['基础环境','机器号','型号','机器名','端口配置']
_func = None
def __init__(self):
self.values = {}
self.senseType = None
self.machineNum = None
self.envType = [] # 环境类型
self.machineNos = [] # 机器号
env = MtInstall.ENVS.get("物理机",None)#类变量调用
mtInstall = MtInstall()
machineNo = mtInstall.machineNum#实例化对象调用成员变量
(2) 实例变量
使用self.var形式创建的变量均为实例变量,有两种创建方法。
# 本例演示实例属性和实例方法的创建
# 以下展示的创建属性的方法比较凌乱,为了规整以后在__init__()方法创建实例属性
class Hero(object):
# 实例属性创建方法1:通过实例方法创建, 不一定是__init__()方法
def create_address(self, address:str):
self.address = address
if __name__ == "__main__":
h = Hero()
# 实例属性创建方法2:可以直接给实例对象添加属性
h.name = "阿喀琉斯"
h.age = 30
h.create_address("希腊")
print("英雄姓名:", h.name)
print("英雄地址:", h.address)
方法
(1) 类方法
使用@classmethod装饰,第一个参数为隐式参数cls,代表类本身:
class mtcomm:
def __init__(self,mchine_no,name):
self.mchineNo = machine_no
self.name = name
@classmethod
def machine_mtcomm(cls,machine_no,name='one'):
return cls(machine_no,name)
machineOne = mtcomm.machine_mtcomm(1)
machineOne = mtcomm.machine_mtcomm(2,'two')
(2) 实例方法
最常见的方法,需注意init此类以双下划线开头和结尾的方法。下面创建的均是实例方法:
class Student(object):
def __init__(self, name:str, age:int):
self.name = name
self.age = age
def set_name(self, name):
'''
修改学生姓名
'''
self.name = name
def get_name(self):
'''
获取学生姓名
'''
return self.name
def set_age(self, age):
'''
修改学生年龄
'''
self.age = age
def get_age(self):
'''
获取学生年龄
'''
return self.age
(3) 静态方法
用@staticmethod关键字修饰,
静态方法与普通的实例方法有什么区别?
静态方法用于类本身,用不到实例对象的引用即self。
什么情况下会要使用静态方法呢?
当这个函数只有这个类调用,其他地方没有调用,单独放到其他地方有显得多余,这个时候我们就使用静态方法
下面我们看一个例子:
class MtCmd:
@staticmethod
def getuser():
'''
获取当前进程用户,windows下默认用windos表示
'''
if sys.platform=='win32':
return 'windos'
else:
return pwd.getpwuid(os.getuid())[0]
@staticmethod
def getgroup(user:str=None)->str:
'''
获取指定用户的所属的组
若user为None则获取当前进程用户所属的组
'''
if sys.platform=='win32':
return 'windos'
elif user is None:
user = MtCmd.getuser()
try:
gid = pwd.getpwnam(user)[3]
return grp.getgrgid(gid)[0]
except KeyError as e:
logging.error('user [%s]->%s',user,e)
return None
这个类定义了两个静态方法函数,一个是getuser(),一个是getgroup()因为这两个函数,只有mtcmd这个类会调用,其他地方不会调用,因此用到静态方法。