python入门基础:类和对象

类和对象

面向对象的思想

⾯向过程:⾯向处理,更多的是从计算机⻆度思考,注重计算每⼀个步骤,程序更像是⼀本cpu操作⼿册。
⾯向对象:以⽇常⽣活的⻆度思考问题的解决,更接近⼈的思维⽅式,让⼈可以从更⾼的层⾯考虑系统的构建

以你请朋友吃饭为例:

面向过程面向对象
自己买菜和朋友一块到饭店
自己摘菜和服务员点菜
自己洗菜和朋友一块吃
自己做菜
和朋友一块吃

面向对象的优点:
面向对象更加合适做应用的开发
面向对象可以使你的代码更加优雅和紧凑
面向对象开发 效率更高
面向对象代码复用度更高,可维护性更好

⾯向对象是⼀种思维⽅式,它认为万事万物皆对象,程序是由多个对象协作共同完成功能的,所以以后我们要从⾯向过程转向⾯向对象。以⾯向对象的⽅式考虑程序的构建。⾯向对象的核⼼是:类和对象

2.类和对象

类和对象的概念
生活角度
**类:**具有系统特征和行为的对象的集合,是一个概念
**对象:**客观存在的一切事物,是类的实例
类:汽车, 电脑, 杯子
对象:红色的宝马, 桌上的mac pro,老王的黑色杯子
程序角度
类:用户自定义的数据类型,是模板,不占用内存
对象:由类定义的变量,占用内存
类:
成员属性(成员变量): 描述对象的静态特征,诸如,名字,身高体重
成员方法:描述对象的动态特征,例如:吃饭,睡觉,打豆豆

类的定义

#语法:
class 类名:
 类体

注意:
1.类定义必须以关键字class开头
2.类名要符合标识符的规范
3.类名⼀般⽤⼤驼峰⻛格: 每个单词⾸字⺟⼤写,其它⼩写 ,例如MyBookYouMoney
4.类体必须缩进
5.在python3中类默认继承object,所以可以这样写 class Dog:,它等价于classDog(object):
6.⼀个⽂件⾥只放⼀个类

成员方法

成员⽅法其实就是函数,作⽤域在类内,成员⽅法的第⼀个参数必须是self,self代表当前对象,也就是调⽤这个⽅法的对象,这个参数由系统传递。

class Dog(object):
 def bark(self): #成员⽅法,第⼀个参数必须是self,代表当前调⽤对象
 print('我是⼩可爱--丁丁')
dingding = Dog() #实例化⼀个对象
#调⽤⽅法,不需要传参数,self是系统传递的
#调⽤形式: 对象.⽅法([实参])
dingding.bark() #等价调⽤形式:bark(dingding)

注意:
1.self参数在调⽤的时候不必传值,由系统传值
2.self只能在实例⽅法中使⽤
3.⽅法和函数的区别:

(1)⽅法作⽤域属于类,所以即便和普通函数重名,也不会被覆盖
(2)⽅法的第⼀个参数必须是self,但函数不要求
(3)⽅法必须通过对象调⽤,⽽函数不需要
4.⽅法的第⼀个参数self其实可以使任何合法标识符,不过⼀般约定俗成都是self
5.⽅法的连贯调⽤

class Dog:
 		def bark(self):
 				print("汪汪汪")
 				return self #返回self
 		def eat(self):
 				print("爱啃⼤⻣头")
 				return self
dog = Dog()
dog.eat().bark() #⽅法的连贯调⽤,⽅法要返回self

对象的创建

对象的创建过程也称之为对象的实例化过程,也就是定义了⼀个类类型的变量或者称之为实例(instance)的过程

#语法: 对象 = 类名([实参])
dingding = Dog() #实例化⼀个对象
print(dingding) #<__main__.Dog object at 0x00000000023F40B8>
print(type(dingding)) #<class '__main__.Dog'>

#查看对象的类名
print(dingding.__class__)

成员属性

成员属性描述的是对象的静态特征,⽐如说狗名字、品种等,其实就是⼀个变量,作⽤域属于对象,不会和类外的全局变量冲突。python中成员属性可以在构造函数中添加。成员属性属于对象,每个对象的成员属性的值都不同

在构造函数中添加的属性属于所有对象(重点)

#添加属性语法:
 对象.成员属性 = 值 #引⽤⽅式:对象.成员属性
class Dog(object):
		 def __init__(self,name,kind,age):
 				self.name = name
 				self.kind = kind
				 self.age = age
 		def bark(tmp):
				 print('我是⼩可爱--丁丁')
dingding = Dog('丁丁','泰迪',3)
print('我是可爱的%s⽝,%s,我今年%d岁了' % (dingding.kind,
dingding.name, dingding.age))


#查看实例属性
print(dingding.__dict__) #__dict__属性可以⽤来查看实例属性
print(dir(dingding)) #查看Dog的属性,包括实例属性

封装

隐藏对象的属性和实现细节,仅对外公开接⼝,控制在程序中属性的读取和修改的访问级别。

类本身就是⼀种封装,通过类可以将数据(属性)和⾏为(⽅法)相结合,形成⼀个有机的整体,也就是将数据与对数据的操作有机的结合。封装的⽬的是增强安全性和简化编程,使⽤者不必了解具体的实现细节,⽽只是要通过外部接⼝,以特定的访问权限来使⽤类的成员。成员私有化是实现封装的⼿段。所有的成员默认是公有。

属性私有化

如果想让类的内部属性不被外界直接访问,可以在这个属性的前⾯加两个下划线__,在Python中,如果⼀个属性的前⾯出现 __,就表示这个属性只能在当前类的⽅法中被直接访问,不能通过对象直接访问,这个变量就被称为私有变量

class Dog:
		 def __init__(self,name,gender,age):
		 		self.name = name
				self._gender = gender #'保护'变量
				self.__age = age #私有变量
 #定义⼀个公开的⽅法,间接访问私有变量
 		def get_age(self):
				 return self.__age
 #定义⼀个公开⽅法,间接设置私有变量
 		def set_age(self,age):
				 self.__age = age
ding = Dog('丁丁','公',5)
print(ding.name)
# print(ding.__age) #AttributeError: 'Dog' object has no attribute
'__age'
print(ding.get_age()) #5 获取私有属性的值
ding.set_age(10) #设置私有属性的值
print(ding.get_age()) #10
print(ding._gender)


#可以通过 _Dog__age访问私有变量,但不建议
print(ding._Dog__age)


【⾯试题】
常⻅的在变量的前后加下划线的问题:
单下划线:_age ----->受保护的 可以访问,当约定俗称,当你看到⼀个下划线开头
的成员时不应该使⽤它
双下划线:__age ------>私有的
两边都双下划线:__age__ ------->系统内置变量

属性装饰器

对于私有属性的访问,使⽤公开⽅法间接访问的⽅法太麻烦,python提供了⼀种便捷语法,属性装饰器,通过属性装饰器,可以很⽅便的对私有属性进访问,属性修饰器可以把⽅法属性化。

class Dog:
    def __init__(self,age):
        self.__age = age

    # get属性装饰器
    @property  # 可以把age方法当属性来使用
    def age(self):
        return self.__age
    #set属性装饰器  名称必须是get属性装饰器中名称
    @age.setter
    def age(self,value):
        self.__age = value

dog = Dog(10)
print(dog.age)
dog.age = 20
print(dog.age)

成员方法私有化

如果对⼀个⽅法的名字前⾯加__,声明该⽅法为私有⽅法,只能在当前类中被调⽤,在外界不能通过对象直接调⽤,这就是私有⽅法

class Dog:
 		def __init__(self,name,age):
 				self.name = name
 				self.age = age
 		def __pee(self):
				 print('这是我的地头')
dog = Dog('dingding',5)
#dog.__pee() #AttributeError: 'Dog' object has no attribute '__pee

构造和析构

构造⽅法

**⽬的:**构造⽅法⽤于初始化对象(不创建对象),可以在构造⽅法中添加成员属性
**时机:**实例化对象的时候⾃动调⽤
**参数:**第⼀个参数必须是self,其它参数根据需要⾃⼰义
**返回值:**不返回值,或者说返回None,不应该返回任何其他值

语法:
 def __init__(self,arg1,arg2....):
 		函数体
#参数:arg1,agr2...根据需要⾃⼰定义
#如果⾃⼰不定义构造⽅法,系统⾃动⽣成⼀个构造函数
def __init__(self):
 	pass

注意:
1.如果没有定义构造⽅法,系统会⽣成⼀个无参构造⽅法,如果⾃⼰定义了构造⽅法,则系统不会⾃动生成

class 类名:
def __init__(self):
pass

2.⼀个类只能有⼀个构造⽅法,如果定义多个,后⾯的会覆盖前⾯的
3.构造函数由系统在实例化对象时⾃动调⽤,不要⾃⼰调⽤

class Dog(object):
 		def __init__(self,name,kind,age):
 				self.name = name #定义对象属性,这个类所有的对象都具有该属性
 				self.kind = kind #成员属性必须通过self.引⽤,否则是普通变量
 				self.age = age
		 def bark(tmp):
				 print('我是⼩可爱--丁丁')
dingding = Dog('丁丁','泰迪',3)
print('我是可爱的%s⽝,%s,我今年%d岁了' % (dingding.kind,
dingding.name, dingding.age))
 

析构⽅法

**⽬的:**对象销毁时,释放资源
**时机:**对象销毁时由系统⾃动调⽤
**参数:**除了self外,没有其他参数
**返回值:**不返回值,或者说返回None。
语法:

def __del__(self):
 #to do
class Dog(object):
   		 #构造
		def __init__(self,name,kind,age):
				self.name = name
				self.kind = kind
				self.age = age
   		 #析构
		def __del__(self):
   			 print('拜拜了,⼆⼗年后⼜是⼀条好汉')
		def bark(tmp):
   			 print('我是⼩可爱--丁丁')
   			 
dingding = Dog('丁丁','泰迪',3)
print('我是可爱的%s⽝,%s,我今年%d岁了' % (dingding.kind,
dingding.name, dingding.age))
del dingding #销毁对象,⾃动调⽤析构⽅法

#在函数中对象,当函数结束运⾏时,⾃动析构
def test():
td = Dog('当当','泰迪',3)

str

⽬的:将对象转化为字符串
时机:凡是涉及对象向字符串转换的都会调⽤(print,str)
参数:self
返回值:字符串

repr 作⽤同 str ,不过是给解释器看的

class Animal:
		 def __init__(self,name,age):
 				self.name = name
 				self.__age =age
 		def __str__(self):
 				return "name : {} age : {}".format(self.name,self.__age)
 		def __repr__(self):
				 return self.__str__()
a1 = Animal('zhu',3)
print(a1)
print('我是⼀头可爱的 ' + str(a1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值