python3基础(十一)-属性和方法的私有化

1、修改类属性

办法1:类名.属性名=值
办法2:类名.方法(传入值)

2、隐藏属性和函数

以两个下划线开始的变量和函数,则称为隐藏属性和隐藏函数。隐藏的变量和函数只能在类里面调用,不能在类外面调用。如果需要在外部修改或访问私有属性值,则需要在类里面提供get和set方法供外部调用。

class User:
#在创建类的时候,获取两个参数值,为私有变量赋值
def __init__(self, name, age):
self.__name = name
self.__age = age

#创建get方法,供类外部调用者获取参数值
def get_name(self):
return self.__name

def get_age(self):
return self.__age

#创建sett方法,供类外部调用者修改参数值
def set_name(self, name):
self.__name = name

def set_age(self, age):
self.__age = age

3、继承
子类继承父类的特性(属性和函数),类似于生活中的父与子的关系。

class Animal:
def __init__(self):
self.color = "黄色"
def eat(self):
self.color = "黄色"
print("------吃饭------")
def sleep(self):
print("------睡觉------")
class Dog(Animal):    #继承于Animal类,单继承
def __init__(self, name):
self.__name = name
def bark(self):
print("------旺旺叫------")
class Cat(Animal):    #继承于Animal类
def catch(self):
print("------抓老鼠------")
dog = Dog()
dog.eat()    #子类可以调用父类的函数

此处要注意,属性的继承和函数的继承有点不一样,子类是不可以直接继承和调用父类的全局变量的。而在这个时候,父类的方法当中创建了一个公有的全局变量,那么如果在子类当中没有重写这个方法,则子类就会调用父类的方法,这个时候对象就会通过这个函数创建一个全局变量。这种情况并不是属性的继承,而是方法的继承,使子类对象通过方法的调用得到了一个新的子类全局变量,不是真正的继承了父类的变量。正如以上父类里面创建的color变量,子类Dog因为重写了__init__()方法,所以在创建Dog对象的时候,不会调用父类里面的__init__()方法所以Dog对象没有为自己创建一个color的属性。而Cat子类却不一样,因为没有重写__init__()方法,所以在创建Cat对象的时候,会自动调用父类的__init__()方法,从而导致创建的Cat对象拥有color属性。这种属性被称为对象属性或实例属性。

4、多继承
多继承是同时继承于多个父类。比如骡子是继承于驴和马。生活中相当于父母与子的关系。

class A:    #类没有指定继承关系的时候,默认是继承于object类
def test(self):
print("A------test()函数")
class B:
def test(self):
print("B------test()函数")
class C(A,B):
def test(self):
print("C------test()函数")
c = C()
print(C.__mro__)    #打印类C多继承调用的优先级关系,其实是跟继承的顺序有关系
c.test()    #调用c类自己的test()函数,因为自己重写了test()函数,如果没有重写此方法,那么则会调用下一个类的test()函数,而下一个类则是继承的类当中的第一个。

5、方法重写
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。
如以上第3点,就是有__init__()方法的重写,虽然此方法本身是object类的方法,但是当子类Dog继承于父类Animal的时候。Animal重写的__init__()方法是object类的,而子类Dog重写的__init__()方法却是父类Animal的,覆盖的也是父类Animal的。所以当Dog类重写了初始化方法后,却导致子类创建对象的时候,不会调用父类里面的初始化方法,从而得不到的color变量值。那么如果要在这种情况下,仍然能够执行重写了的父类的方法,我们就需要主动调用。

def __init__(self, name):
super().__init__()    #主动调用父类的初始化方法即可,这里因为父类没有参数,所以不用传参
self.__name = name

6、多态与类属性
多态在python当中是个弱类型。所谓强类型和弱类型,是指在申明变量的时候,有没有明确的指定这个变量的类型,如果指定了,就是强类型,而没有明确指定变量类型就属于弱类型。python就属于不指定类型的弱类型。

前面在继承中用到的属性,就是实例属性(对象属性),顾名思义类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。
类属性:所属类,这个类下所有的对象都可以共享这个类属性。相当于java中静态属性。在python当中,直接在类中申明一个变量就是公共的类属性。如以下的name。

class User(object):
	name = "zhantao"#公共的类属性
	__password = "123456"#私有(隐藏)的类属性
	def __init__(self, sex, username):
		super(User, self).__init__()
		self.sex = sex#对象属性
		self.username = username#对象属性
 #self.name = username#name是对象属性,而不是修改全局的类属性,这个跟Java当中的是完全不一样。
		
u1 = User("男", "goldfish”)
print(u1.name)

u2 = User("女", "love)
print(u2.name)

print(User.name)
以上u1,u2两个对象打印出来的值和使用类名调用变量打印出来的值是一样的

u1.name = "ww"#这里仅仅是修改了u1对象里面的类属性,而没有修改类里面的属性。因为类属性是属于类的,而不是属于某个对象的,所以要修改则需要通过类名来修改。
User.name = "ww"#这才是真正修改了公共的类属性
del u1.name#本质上只是删除了对象u1的name属性,并没有删除类里面的属性

7、类方法
构建一个类方法,则在一个公共方法上面加上一个修饰器@classmethod,此方法仍然可以被继承

class User(object):
 name = "zs"
	@classmethod    #类方法一定要在方法的上面加上一个修饰器
	def name(cls):    #其中参数不是self,而是cls,cls代表的是类本身,而self代表的是对象本身
cls.name = "ww"    #因为cls代表类本身,所以可以通过这种方式来修改类属性,同User.name = "ww"是同样的效果
print("-------")
user = User()
user.name()
User.name()
以上调用的结果是一致的,同一个方法。

8、静态方法
静态方法属于类方法的一种,只不过修饰符不一样,需要使用@staticmethod,也是属于类的方法。
区别:没有默认传递参数。这里所说的没有默认传递参数,并不是说没有参数,当然在方法里面也可以定义形参,只不过不像类方法那样,系统会自动的传入一些默认的参数(self和cls)。但是一但自己定义了参数,则调用的时候就必须要传入参数才行。

class User(object):
	@staticmethod
	def age():
		User.name = "ww"    #在这里修改全局变量则需要使用类名了,没有默认的cls使用。

总结:
1、python中没有像c++中public和private这些关键字来区别公有属性和私有属性
2、它是以属性命名方式来区分,如果在属性名前加了两个下划线,则表明该属性是私有属性,否则为公有属性(函数也是一样的)。公有属性即可以通过类名来访问,也可以通过对象来访问。
3、继承仅仅是继承父类的公共方法和公共的类属性。
4、类属性是属于类的,而不是属于某个对象的,所以要修改则需要通过类名来修改。
5、如果对象属性有和类属性名字一模一样的,那么通过对象调用,则是调用的对象属性,值也是对象属性的值。此时需要用到公共的类属性,则需要通过类名来调用。(这一点是完全和java不一样的),在python当中,对象属性和类属性是完全分开的。
6、公共方法和类方法里面的self和cls形参名字可不可以随便修改?当然是可以的,只是一个参数名字而已,只是我们需要做到见其名知其意,所以习惯性的用self代表对象本身,使用cls代表类本身。

作者:沧水巫云
博客:http://blog.csdn.NET/amir_zt/
以上原创,转载请注明出处,谢谢。
https://blog.csdn.net/amir_zt/article/details/84201777

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值