封装,property,绑定方法与非绑定方法

一.封装

面向对象三大特征:

封装,继承,多态

最重要的一个特性就是封装,封装就是把数据和功能整合到一起.所以封装==整合

在封装的基础上,我们可以将装到对象或类中的属性隐藏起来,注意:

(1).在定义或者初始化对象时,在属性前加__,就会将该属性隐藏起来,但该隐藏起始只是一种变形_类名__属性名,并没有真正的隐藏起来
(2)该变形操作是在类定义阶段扫描语法时发生的变形,类定义之后添加的__开头的属性不会发生变形
(3)该隐藏是对外不对内的
(4)在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

例1:

class Student:
	__school = 'oldboy'  # _Student__school = 'oldboy'

	def __init__(self,x,y,z):
		self.__name = x  # self._Student__name = x
		self.age = y
		self.gender = z

	def __choose(self):	  # self._Student__choose
		print('%s 正在选课' % self.name)

stu_obj1 = Student('冯疯子',18,'female')
# stu_obj1.__x = 111
# print(stu_obj1.__dict__)  # {'_Student__name': '冯疯子', 'age': 18, 'gender': 'female', '__x': 111}
# print(stu_obj1.__x)  # 111

print(stu_obj1.__dict__)  # {'_Student__name': '冯疯子', 'age': 18, 'gender': 'female'}
print(stu_obj1._Student__name)  # 冯疯子

print(Student.__dict__)  # {'__module__': '__main__', '_Student__school': 'oldboy', '__init__': <function Student.__init__ at 0x000002322B72E550>, '_Student__choose': <function Student.__choose at 0x000002322B8E5040>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
print(Student._Student__school)  # oldboy
print(stu_obj1._Student__school)  # oldboy

隐藏属性的意义:

1.把数据属性隐藏起来的意义:
	在类内开放接口,让外界使用者通过接口来操作属性值,我们可以在接口之上附加任意的逻辑来严格控制外界使用者对属性的操作
2.把功能属性隐藏起来:
	隔离复杂度

1.把数据属性隐藏起来的意义:

class Student:
	__school = 'oldboy'  # _Student__school = 'oldboy'
	def __init__(self,x,y,z):
		self.__name = x  # obj._Student__name = x
		self.__age = y
		self.gender = z

	def __choose(self):  # obj.__Student__choose
		print('%s 正在选课' % self.name)

	def get_name(self):
		print(self.__name)

	def set_age(self,x):
		if type(x) is not int:
			print('年龄必须是整型,傻叉')
			return
		self.__age = x

	def get_age(self):
		print(self.__age)

	def del_age(self):
		del self.__age

stu_obj1 = Student('冯疯子',18,'female')
stu_obj1.get_name()  # 冯疯子

stu_obj1.set_age('asfdasdf')
# stu_obj1.set_age(19)
# stu_obj1.get_age()
print(stu_obj1.__dict__)  # {'_Student__name': '冯疯子', '_Student__age': 18, 'gender': 'female'}

2.把功能属性隐藏起来:隔离复杂度

例如ATM程序的取款功能,该功能有很多其他功能组成,比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能接口即可,其余功能我们都可以隐藏起来

class ATM:
	def __card(self):
		print('插卡')
	def __auth(self):
		print('用户认证')
	def __input(self):
		print('输入存款金额')
	def __print_bill(self):
		print('打印账单')
	def __take_money(self):
		print('取款')

	def withdraw(self):
		self.__card()
		self.__auth()
		self.__input()
		self.__print_bill()
		self.__take_money()

a = ATM()
a.withdraw()

二.property

property这个装饰器,可以将类中的函数“伪装成”对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次访问的结果

例1:

class People:
    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)


p = People('egon', 1.81, 70)
p.height = 1.84
print(p.bmi)

例2:

class Student:
	__school = 'oldboy'

	def __init__(self,x,y,z):
		self.__name = x
		self.__age = y
		self.gender = z

	def get_name(self):
		print('访问控制')
		return self.__name

	def set_name(self,x):
		print('赋值操作')
		self.__name = x

	def del_name(self):
		print('删除操作')
		del self.__name

	def get_age(self):
		return self.__age

	def set_age(self,x):
		if type(x) is not int:
			print('年龄必须是整型,傻叉')
			return
		self.__age=x

	def del_age(self):
		print('不让删')

	age = property(get_age,set_age,del_age)
	name = property(get_name,set_name,del_name)

stu_obj1 = Student('冯疯子',18,'female')

print(stu_obj1)
stu_obj1.age = '19'
del stu_obj1.age
print(stu_obj1.age)

print(stu_obj1.name)
stu_obj1.name='EGON'
del stu_obj1.name 

使用property有效地保证了属性访问的一致性。另外property还提供设置和删除属性的功能

例3:

class Student:
	__school = 'oldboy'

	def __init__(self,x,y,z):
		self.__name = x
		self.__age = y
		self.gender = z


	@property
	def name(self):
		print('访问控制')
		return self.__name

	@name.setter
	def name(self,x):
		print('赋值控制')
		self.__name = x

	@name.deleter
	def name(self):
		print('删除控制')
		del self.__name

stu_obj1 = Student('冯疯子',18,'female')

stu_obj1.name

三.绑定方法与非绑定方法

类中的定义的函数分为2大类:绑定方法与非绑定方法

1.绑定方法:谁来调用就会将谁当作第一个参数传入

(1)绑定给对象的方法:类中定义的函数默认就是绑定给对象的方法,应该是由对象调用,会把对象当做第一个参数传入
(2)绑定给类的方法:在类中的函数上加一个装饰器@classmethod,该函数就绑定给类了,应该是由类来调用,会把类当做第一个参数传入

2.非绑定方法:既不与类绑定也不与对象绑定,就是一个普通的函数,谁都可以来调用,没有自动传参的效果,在函数上添加装饰器@staticmethod

class People:
	def __init__(self,name,age):
		self.name = name
		self.age = age

	def tell_info(self):
		print('<%s:%s>'%(self.name,self.age))

	@classmethod
	def f1(cls):
		print(cls)

	@staticmethod
	def f2(x,y,z):
		print(x,y,z)

p1 = People('egon',18)
p1.tell_info()  # <egon:18>

print(p1.tell_info)  # <bound method People.tell_info of <__main__.People object at 0x000001E0FB535D30>>
print(People.f1)  # <bound method People.f1 of <class '__main__.People'>>

People.f1()  # <class '__main__.People'>

print(p1.f2)  # <function People.f2 at 0x00000116D74E5700>
print(People.f2)  # <function People.f2 at 0x00000116D74E5700>

p1.f2(1,2,3)  # 123
People.f2(1,2,3)  # 123
# settings.py文件内容
IP = "127.0.0.1"
PORT = 3306

import uuid
import settings

class MySQL:
	def __init__(self,ip,port):
		self.mid=self.__created_id()
		self.ip = ip
		self.port = port

	def tell_info(self):
		print('%s:<%s:%s>'%(self.mid,self.ip,self.port))

	@staticmethod
	def __created_id():
		return uuid.uuid4()

	@classmethod
	def from_conf(cls):
		return cls(settings.IP,settings.PORT)

obj = MySQL('10.10.11.11',3306)
obj.tell_info()

obj1 = MySQL.from_conf()
obj1.tell_info()

总结绑定方法与非绑定方法的使用:

若类中需要一个功能,该功能的实现代码中需要引用对象则将其定义成对象方法、
需要引用类则将其定义成类方法、无需引用类或对象则将其定义成静态方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值