封装
综上所述:面向对象共有三种方法,继承与派生,多态性,以及最后的封装。
封装指的是什么?
封装其实就是将数据与功能的整合,以及我们可以通过封装做到将封装对象的属性以及方法进行隐藏。
如何隐藏
python中的Class通过使用双下划线的方式将属性隐藏
class Test:
def __init__(self,name,age):
#本质是一种变形操作_self__name
self.__name = name # _Test__name
self.__age = age
test = Test('sadnesspineapple',18)
test.__name
#如何访问隐藏的属性
class Test:
def __init__(self,name,age):
self.__name = name
self.__age = age
test = Test('sadnesspineapple',18)
print(test._Test__name)
虽然我们也可以通过变形的操作访问到属性,但是毫无疑问我们隐藏的目的就不是让人直接访问,因此这是毫无意义的。
在类的内部我们则是可以直接访问我们需要的属性,但是这也仅仅只限于在定义阶段就写好的属性,后续添加的属性则是无法变形,可以使用普通的方法访问。
#在类的内部访问
class Test:
def __init__(self,name,age):
self.__name = name
self.__age = age
def tell_name(self):
print(self.__name)
test = Test('sadnesspineapple',18)
test.tell_name()
>>>sadnesspineapple
#后续添加属性进行访问
class Test:
def __init__(self,name,age):
self.__name = name
self.__age = age
def tell_name(self):
print(self.__name)
test = Test('sadnesspineapple',18)
test.__sex = 'male'
print(test.__sex)
>>>male
将数据属性隐藏起来的意义
我们创建属性,接口的意义就是为了让人访问,因此隐藏属性其实不是我们真正的目的
当我们将内部的属性进行封装之后,我们可以在内部为这些属性提供一个接口,以便让外界改变内部的属性
也就是说,我们可以让外界不直接访问内部的类,但是我们可以允许外界间接的访问我们内部的属性
对属性进行隐藏
#会报错
class Test:
def __init__(self,name,age):
self.__name = name
self.__age = age
def set_name(self,name,age):
if not name.isdigit():#名字如果是数字则不能修改
self.__name =name
self.__age = age
test = Test('sadne',18)
test.set_name(20,18)
#我们可以进行设置,只有满足我们的条件才能对属性进行修改
对类进行隐藏
#有些时候我们创建类并不是为了让外界调用,这种时候我们可以使用隐藏的方法
class Test:
def __init__(self, name, age):
self.__name = name
self.__age = age
def __pr_name(self):
print(self.__name)
def set_name(self, name, age):
if not name.isdigit():
self.__name = name
self.__age = age
self.__pr_name()
test = Test('sadne', 18)
test.set_name('sa', 18)
>>>sa
property
这个是python解释器的内置方法。
他的效果主要是将函数伪装成属性的形式,使用这个装饰器的话必须要有返回值
class Test:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
test = Test('sadne', 18)
print(test.name)
如上图我们本来需要使用的是name()才能得到name的值,但是现在我们只需要使用name就可以获得了
另外property还提供了设置以及删除方法
class Test:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
@name.setter # 调用赋值操作时会调用
def name(self, value):
self.__name = value
@name.deleter#调用del操作时会调用
def name(self):
pass
test = Test('sadne', 18)
test.name = 20
print(test.name)
>>>20
本质类似于装饰器
绑定方法与非绑定方法
Class中定义的函数分为两大类:绑定方法与非绑定方法
绑定方法又分为两种:绑定给类,绑定给对象
而在python中,默认的则是绑定给对象
绑定方法
若需要绑定给类,则需要在需要被绑定的方法上面添加@classmethod
#tests里面的内容
name = 'sadnesspineapple'
age = 18
#主程序的方法
import tests
class People:
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def from_test(cls):
#必须要返回一个对象
return cls(tests.name,tests.age)
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
people = People.from_test() #People.from_test() = People(tests.name,tests.age)
print(people.name)
至于绑定对象则是如我们平时一样直接调用即可
非绑定方法
在我们编写程序的时候有时候有些类本身并不需要传入任何参数,只需要直接调用即可,这种时候你若使用普通的绑定方法然后去调用函数他会报错。因为我们直接将一个对象传给了他即self
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def test():
print('aaaa')
student = Student('shi',18)
student.test()
>>>TypeError: test() takes 0 positional arguments but 1 was given
@staticmethod
def test():
print('aaaa')
这种时候我们只需要在该方法上面添加一个@staticmethod即可以不把self作为参数传入。