2022-10-09 python私有属性和私有方法

文章参考:(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这个类会调用,其他地方不会调用,因此用到静态方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容