python 类 私有属性、私有方法_Python类的私有属性与私有方法的使用

转自:https://blog.csdn.net/qq_36171645/article/details/89340862

请运行下面代码尝试(如果搞不定,先看后面的讲解,再尝试):

*xx: 公有变量

_x: 单前置下划线,私有化属性或方法,from somemodule import 禁止导入,类对象和子类可以访问

_xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)

xx:双前后下划线,用户名字空间的魔法对象或属性。例如:init , __ 不要自己发明这样的名字

xx:单后置下划线,用于避免与Python关键词的冲突

通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者属性)如:_Class__object)机制就可以访问private了。

#coding=utf-8

class Person(object):

def __init__(self, name, age, taste):

self.name = name

self._age = age

self.__taste = taste

def showperson(self):

print(self.name)

print(self._age)

print(self.__taste)

def dowork(self):

self._work()

self.__away()

def _work(self):

print('my _work')

def __away(self):

print('my __away')

class Student(Person):

def construction(self, name, age, taste):

self.name = name

self._age = age

self.__taste = taste

def showstudent(self):

print(self.name)

print(self._age)

print(self.__taste)

@staticmethod

def testbug():

_Bug.showbug()

# 模块内可以访问,当from cur_module import *时,不导入

class _Bug(object):

@staticmethod

def showbug():

print("showbug")

s1 = Student('jack', 25, 'football')

s1.showperson()

print('*'*20)

# 无法访问__taste,导致报错

# s1.showstudent()

s1.construction('rose', 30, 'basketball')

s1.showperson()

print('*'*20)

s1.showstudent()

print('*'*20)

Student.testbug()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

dc553fb54364beb67cfa48a0c27680b6.png

————————————————这就是后面的讲解——————————————————

1.Python中属性:类属性 ,实例属性,私有属性的使用

在Python中的属性分为:类属性和对象(实例)属性:

1.类属性就是属于类所有,可以直接用类名.属性名直接调用,类的属性在内存中只有一份。实例属性就是在__init__()方法中初始化的属性;

2.实例属性属于类的对象所有,可以用对象名.属性名的形式进行调用,但是不能用类名.属性名进行调用 。因为实例属性只有在实例创建时,才会初始化创建。

#1.类属性和实例的属性的调用关系

class Person:

country ="china" #类属性

def __init__(self,name,age):

sex ="男" #这不是实例属性,只是变量而已,用对象名.sex调不出来。

self.name = name #实例属性

self.age = age

#创建对象

print(Person.country)

#print(Person.age) 出错,AttributeError: type object 'Person' has no attribute 'age'

p1 = Person("tom",12)

print(p1.country,p1.age,p1.name,p1)

----------结果如下------------------------------------------------------------------------

china

china 12 tom

----------------------------------------------------------------------------------------

#2.修改类属性和实例属性:类属性只能通过类名.属性才可以修改

class Person:

country ="china" #类属性

def __init__(self,name,age):

sex ="男" #这不是实例属性,只是变量而已,用对象名.sex调不出来。

self.name = name #实例属性

self.age = age

-------创建对象-------------------------------------------------------------------------

p1.country = "america"

print(p1.country) #通过实例去修改属性,实例的属性修改了:america

print(Person.country)#但是类的属性还是没有修改:china

Person.country = "japan" #只有用类名.属性名才能修改类的属性值。

p2= Person("jack",11)

print("p1.country:",p1.country)

print("p2.country",p2.country)

print("Person.country",Person.country)

------结果如下-----------------------------------------------------------------------------

america

china

p1.country: america

p2.country japan

Person.country japan

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

实际开发中为了程序的安全,关于类的属性都会封装起来,Python中为了更好的保存属性安全,即不能随意修改。一般属性的处理方式为:1.将属性定义为私有属性。2.添加一个可以调用的方法,供调用。

3.Python中用__两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问

class Person1(object):

country ='china' #类属性

__language ="Chinese" #私有类属性也不能直接外部调用

def __init__(self,name,age):

self.name = name

self.__age = age #使用__下划线表示私有属性,对象不能直接调用,要通过方法调调用

def getAge(self):

return self.__age

def setAge(self,age):

if age >100 or age <0:

print("age is not true")

else :

self.__age = age

def __str__(self):

info = "name :"+self.name +",age(保密):"+str(self.__age) #注意这里不是self.age

return info

#------创建对象,调用方法,属性测试-------------------------------------------------------

stu1 = Person1("tom",18)

print("修改前的结果:",stu1.__str__())

stu1.name="tom_2" #修改stu1的name属性

print("修改name后的结果:",stu1.__str__())

#print(stu1.__age) #直接调用私有属性__age报错,'Person1' object has no attribute '__age'

print("打印私有age内存地址:",id(stu1.getAge()))

stu1.__age = 19 #如果这样赋值的话,不会报错,因为系统找不到这个变量,直接新建了一个。但是实际没有修改对象的属性值

print(stu1.__age) #有值,但是没有 实际修改stu1对象的age属性值

print("打印stu1.__age的内存地:",id(stu1.__age)) #两个内存地址值不一样。

print("错误修改age后的值",stu1.__str__()) #实际值没有变

stu1.setAge(22) #只有调用才可以修改age的值

print("正确修改age后的值",stu1.__str__())

'''执行结果如下:

修改前的结果: name :tom,age(保密):18

修改name后的结果: name :tom_2,age(保密):18

打印私有age内存地址: 1388146224

19

打印stu1.__age的内存地: 1388146256

错误修改age后的值 name :tom_2,age(保密):18

正确修改age后的值 name :tom_2,age(保密):22

'''

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

2.私有方法,类方法,静态方法的使用

1.私有方法:以 __两个下划线开头,声明该方法为私有方法,只能在类的内部调用 (类内部别的方法可以调用他),不能在类地外部调用。

c

lass Person5:

def __p(self):

print("这是私有属性") #内部函数也同样可以任意之间互相调用

def p1(self):

print("这是p1不是私有方法")

def p2(self):

print("这是p2,可以调用p1,也可以调用私有方法__p")

self.p1()

self.__p()

#创建对象

c1 = Person5()

c1.p1()

c1.p2()

#c1.__p() #不能直接私有函数。报错。注意区分系统自带的函数如__str__,外部可以直接调用的。

'''结果如下:

这是p1不是私有方法

这是p2,可以调用p1,也可以调用私有方法__p

这是p1不是私有方法

这是私有属性

'''

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

2.类方法的使用:是类所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,也可以有别的参数。但是第一个必须是类对象,类似类中的def定义的普通方法第一个参数要是self一样的道理

class People(object):

country = 'china'

#类方法,用classmethod来进行修饰,跟普通的方法区别就是可以直接通过类名.方法名的方式调用

@classmethod

def getCountry(cls):

return cls.country

@classmethod

def sum(cls,a,b):

return a+b

p = People()

print (p.getCountry()) #可以用过实例对象引用

print (People.getCountry() ) #可以通过类名.方法名的形式调用

print(p.sum(10,11))

print(People.sum(10,11))

====================================================================================

china

china

21

21

3.静态方法:需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

class People(object):

country = 'china'

@staticmethod

#静态方法,不用定义参数

def getCountry():

return People.country

print (People.getCountry())

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

3.方法的使用注意要点

注意python中不支持方法的重载:即方法名相同,参数类型(参数个数不同)不同的函数,python中 不支持。

def p():

print("dd")

def p(a,b):

print("dd")

def p(a):

print("dd")

p()#报错,因为python中不需要定义参数的类型。如果有多个重载的函数,则python默认只能使用最后一个有效。

所以只能调用P(a)这个函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值