知识点 —— Python进阶-2
Posted 海绵小青年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识点 —— Python进阶-2相关的知识,希望对你有一定的参考价值。
Python进阶–2
面向对象–基础
- 引入理解
https://blog.csdn.net/shenzixincaiji/article/details/83576687
类、对象、属性、方法
- 基础
class student: # 类 age = 18 # 类的属性 tall = 175 phone = 'huawei' def sleep(self): # 类的方法 print('正在睡觉') # basic # 对象lily和对象Tom继承student类,两者的数据id一致 lily = student() print(lily.age, lily.tall, lily.phone) print('lily.age的id:', id(lily.age)) lily.sleep() Tom = student() print(Tom.age, Tom.tall, Tom.phone) print('Tom.age的id:', id(Tom.age)) Tom.sleep() print('----------------------------------------') # change 类 student.age = 20 # 第一次改变类属性,两个对象的属性也一起改变 print(lily.age, Tom.age) # 即对两个对象都有影响 print(id(lily.age), id(Tom.age)) print('----------------------------------------') # change 对象lily lily.age = 19 # 改变对象lily的属性(对象属性),创建了动态的对象属性与起绑定 print(lily.age, Tom.age) # 改变的结果不影响另一个对象的属性 print(id(lily.age), id(Tom.age)) print('----------------------------------------') # change 类 student.age = 21 # 再次改变类属性,lily的属性已经不受影响,Tom的属性仍会受到影响 print(lily.age, Tom.age) print(id(lily.age), id(Tom.age))
- 高级一点
class student: tall = 'None' # 类属性,其变化同于基础部分的讲解 def __init__(self): # 魔术方法 self.name = 'None' # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改 self.age = 'None' self.phone = 'None' def sleep(self): print('{}正在睡觉'.format(self.name)) # self就相当于具体的对象 # basic lily = student() print(lily.age, lily.name, lily.phone) print('lily.age的id:', id(lily.age)) lily.sleep() # self.name == lily.name Tom = student() print(Tom.age, Tom.name, Tom.phone) print('Tom.age的id:', id(Tom.age)) Tom.sleep() # self.name == Tom.name print('----------------------------------') # 初始化后的具体赋值 lily.name = 'lily' lily.age = '15' lily.phone = 'huawei' print(lily.age, lily.name, lily.phone) print('lily.age的id:', id(lily.age)) lily.sleep() print('----------------------------------') Tom.name = 'Tom' Tom.age = '15' Tom.phone = 'iphone' print(Tom.age, Tom.name, Tom.phone) print('Tom.age的id:', id(Tom.age)) Tom.sleep()
- 总结
类属性
使用同一类创建不同的对象
- 若没有改变过类属性,可以通过类属性改变,来改变对象中对应类属性的值。一起改变
- 若某一对象更改了类属性的值,则建立动态对象绑定,此对象中类属性变为修改后的数值;其他对象的类属性不变
- 再次改变类属性,已经动态绑定的对象,其对象的类属性不会受到影响;对于没有“私自”更改类属性的对象,其对应的类属性仍然会受到影响
对象属性
对象属性是依据类创建对象的时候,每个对象都具有的公共属性
其数值的更改需要通过调用对象属性赋值来修改,不能通过类属性更改
总结
类属性,不允许对象私自修改,有类统一修改,影响所有对象
对象属性,依据对象的特点,可以自己做出特定的修改。类没有权限去修改对象属性
对象方法
- 理解
class student(object):
tall = 'tom' # 类属性,其变化同于基础部分的讲解
def __init__(self, nickname): # 魔术方法
self.name = nickname # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改
self.age = 'None'
self.phone = 'None'
def run(self):
print("{}在跑步".format(self.name)) # 调用对象属性
print("{}在跑步".format(self.tall)) # 调用类属性
self.sleep() # 调用其他对象方法
def sleep(self):
print('在睡觉')
# basic
lily = student('dahuang')
lily.sleep()
lily.run()
在睡觉
dahuang在跑步
tom在跑步
在睡觉
对象方法
可以调用类属性,也可以调用对象属性
对象方法中的参数是对象self
对象方法之间可以相互调用
类方法
- 理解
class student(object):
tall = 'tom' # 类属性,其变化同于基础部分的讲解
def __init__(self, nickname): # 魔术方法
self.name = nickname # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改
self.age = 'None'
self.phone = 'None'
def sleep(self):
print('在睡觉')
@classmethod
def test(cls):
print('只能调用类属性:',cls.tall)
# basic
student.test()
只能调用类属性: tom
类方法
依赖装饰器,且只能调用类属性,不能调用对象属性(会报错)
类方法中的参数是类,不依赖对象,可以独立于对象做一些处理
类方法中不能调用对象方法
- 类方法和对象方法的理解
类属性是公共属性,对象属性是私有属性
类方法只能调用类属性;而对象方法既能调用对象属性,也能调用类属性
静态方法
class student(object):
__tall = 'tom' # 对类属性进行私有化
high = 12
def __init__(self, nickname):
self.name = nickname
self.age = 'None'
self.phone = 'None'
def sleep(self):
print('在睡觉')
@staticmethod
def casual():
print('只能调用类属性tall:', student.__tall)
print('只能调用类属性high:', student.high)
# basic
student.casual()
只能调用类属性tall: tom
只能调用类属性high: 12
也是只能访问公共类属性
静态方法和类方法区别
不同
- 装饰器不同
- 参数不同,一个有cls,一个无cls
相同
- 都只能访问类属性和方法,对象属性和对象方法无法访问
- 都可以通过类名调用访问
- 都可以在对象创建之前调用,不依赖于对象
总结–↑
- 几种方法都可以接受外部参数
class student(object):
__tall = 'tom' # 对类属性进行私有化
high = 12
def __init__(self, nickname):
self.name = nickname
self.age = 'None'
self.phone = 'None'
def sleep(self, outer1):
print('outer1:', outer1, self.__tall, self.high)
@classmethod
def casual(cls, outer2):
print('outer2:', outer2, cls.__tall, cls.high)
@staticmethod
def casual(outer3):
print('outer3:', outer3, student.__tall, student.high)
# basic
student('dahuang').sleep(1)
student.casual(2)
student.casual(3)
outer1: 1 tom 12
outer3: 2 tom 12
outer3: 3 tom 12
- 各自特点
对象方法
- 可以调用对象属性,也可以调用类属性(私有和非私有的)
- 依赖对象,没有对象就不能调用对象方法
- 没有装饰器
- 必须有self对象参数,也可以有外部参数
类方法
- 只能调用类属性(私有的和非私有的)
- 不依赖对象,没有对象也可以调用类方法
- 需要装饰器,classmethod
- 必须有cls参数,也可以有其他外部参数
静态方法
- 只能调用类属性(私有和非私有的)
- 不依赖对象,没有对象也可以调用静态方法
- 需要装饰器,staticmethod
- 不需要任何参数,但是也可以添加外部参数
面向对象–魔术方法
魔术方法
- http://c.biancheng.net/view/7817.html
- https://www.cnblogs.com/zhangboblogs/p/7860929.html
- https://www.cnblogs.com/nmb-musen/p/10861536.html
常用魔术方法
# __str__(self)
# __new__(self)
面向对象–私有化
类属性的私有化
- 目的
为了防止外部任意修改公共类属性
私有化的类属性只能够被类方法修改
class student(object):
__tall = 'tom' # 对类属性进行私有化
high = 12
def __init__(self, nickname):
self.name = nickname
self.age = 'None'
self.phone = 'None'
def sleep(self):
print('在睡觉')
@classmethod
def test(cls):
print('只能调用类属性tall:',cls.__tall)
print('只能调用类属性high:', cls.high)
@classmethod
def update(cls):
cls.__tall = '把tom改为tttom'
# basic
student.test()
student.high = '修改后'
student.tall = '修改后' # 私有属性,不可外界修改
student.test()
student.update() # 使用类方法修改私有属性
student.test()
只能调用类属性tall: tom
只能调用类属性high: 12
只能调用类属性tall: tom
只能调用类属性high: 修改后
只能调用类属性tall: 把tom改为tttom
只能调用类属性high: 修改后
对象属性的私有化
- 目的
为了防止对象属性被不合理的修改
可以通过对象方法来修改私有的对象属性
class PositiveInteger():
def __init__(self):
self.__name = 'Tom'
self.__age = 15
def setName(self, newname):
self.__name = newname
def setAge(self, newage):
if 0 < newage < 100:
self.__age = newage
else:
print('年龄不符合要求')
def __str__(self):
return '学生的年龄:{},学生的名字:{}'.format(self.__age, self.__name)
i = PositiveInteger()
print(i)
# i.__name 这是无法修改的
i.setName('TTTTom')
i.setAge(150)
print(i)
学生的年龄:15,学生的名字:Tom
年龄不符合要求
学生的年龄:15,学生的名字:TTTTom
私有化的本质–↑
- 本质是通过修改内部的名字,让你无法通过原名字访问
- 可以找到真实的名字进行访问,但是不建议这样用
class PositiveInteger():
__name1 = 'lily'
def __init__(self):
self.__name = 'Tom'
self.__age = 15
def setName(self, newname):
self.__name = newname
def setAge(self, newage):
if 0 < newage < 100:
self.__age = newage
else:
print('年龄不符合要求')
def __str__(self):
return '学生的年龄:{},学生的名字:{}'.format(self.__age, self.__name)
i = PositiveInteger()
print(dir(PositiveInteger))
print(dir(i)) # 等价于 i.__dir__()
print(i)
i._PositiveInteger__age = 99 # 不过不建议这样修改
print(i)
学生的年龄:15,学生的名字:Tom
学生的年龄:99,学生的名字:Tom
@property
- 目的
即想达到对象属性私有化的目的
又想通过 对象.属性 的方法来调用和修改私有化后的属性
class PositiveInteger():
def __init__(self):
self.name = 'Tom'
self.__age = 15
@property
def age(self):
return self.__age
@age.setter
def age(self, newage):
if 0 < newage < 100:
self.__age = newage
else:
print('年龄不符合要求')
def __str__(self):
return '学生的年龄:{},学生的名字:{}'.format(self.__age, self.name)
i = PositiveInteger()
print(i, i.age)
i.age = 99
print(i, i.age)
学生的年龄:15,学生的名字:Tom 15
学生的年龄:99,学生的名字:Tom 99
面向对象–关联关系
概念辨析
- is a
是一种继承关系
A is a B B是A的基类(父类)
可以产生代码上的重用性
比如:兔子 is a 动物
就是说兔子继承了动物的一些特点:有腿、有耳朵
具体到代码层面就是说:它可以继承动物(父)类的一些属性,如果有需要增加的可以再写
兔子爱吃的素食有哪些,就是兔子类不能从动物类继承的属性,因为有些动物不吃素的
就可以在动物类的基础上,添加喜欢吃的食物这一属性
- has a
是一种包含关系
A has a B A包含B
比如:汽车 has a 轮胎,但是不能说汽车 is a 轮胎
包含关系具体到代码层面就是调用
汽车有很多属性:轮胎类型、车座类型、价格…
轮胎也有很多属性:价格、材质、防滑等级…
汽车对象就可以调用轮胎对象里面的一些属性
宝马牌汽车的轮胎是米其林材质的,价格是…。防滑等级是…
实例理解
讲的是 has a的包含关系
is a的继承关系在后续有介绍
class Compter:
def __init__(self,brand,type,color):
self.brand=brand
self.type=type
self.color=color
def online(self):
print("正在使用电脑上网")
def __str__(self):
return self.brand + '-------'+self.type+'------'+self.color
class Book:
def __init__(self,bname,number,author):
self.bname=bname
self.number=number
self.author=author
def __str__(self):
return self.bname+self.author+self.number
class sudent:
def __init__(self,name,compter,book):
self.name=name
self.compter=compter
self.Book=[]
self.Book.append(book)
def __str__(self):
return self.name+'------->'+str(self.compter)+'-----'+str(self.Book)
C=Compter('mac','pro','深灰色')
print(C)
print(type(C))
s = sudent('lilu', C, '盗墓笔记')
print(s)
mac-------pro------深灰色
<class ‘main.Compter’>
lilu------->mac-------pro------深灰色-----[‘盗墓笔记’]
面向对象–继承关系
基本继承
class person():
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
print('{}岁的{}在跑步'.format(self.age, self.name))
class sudent(person):
def __init__(self, name, age, classes):
super().__init__(name, age )
self.classes = classes
def run(self, food):
super().run()
print('他是{}的,喜欢吃{}'.format(self.classes, food))
s = person('lilu', 13)
s.run()
s = sudent('lilu', 14, '15班')
s.run('汉堡')
13岁的lilu在跑步
14岁的lilu在跑步
他是15班的,喜欢吃汉堡
- init问题
子类不定义init,则从父类继承
子类继承父类,但是也需要自己定义
def __init__(self, name, age, classes):
super().__init__(name, age)
self.classes = classes
- 对象方法
父类定义eat()对象方法,子类无定义
参数结果均同于父类
默认搜索原则:先搜索当前类,没有的话,再搜索父类
父类定义eat()方法,子类也定义
父类提供的方法无法满足子类需求,在子类中定义一个同名的方法,就叫做:重写
子类定义的同名方法,可以借助父类中定义的部分
def run(self, food):
super().run()
print('他是{}的,喜欢吃{}'.format(self.classes, food))
- 注意
父类中私有的属性,子类是无法继承的
多重继承
- https://www.cnblogs.com/xpc51/p/11764975.html
class Base()以上是关于知识点 —— Python进阶-2的主要内容,如果未能解决你的问题,请参考以下文章