知识点 —— 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
常用魔术方法
# __new__(self) 和 __init__(self)
# 先执行new,再执行init,不要随便动用new魔术方法
class Test:
def __init__(self):
print("init方法")
def __new__(cls, *args, **kwargs):
print("重写new方法")
return super().__new__(cls)
m = Test()
重写new方法
init方法
# _del__(self) :析构器
# 当一个实例被销毁的时候调用的方法
# 非手动调用时会在程序最后触发,而手动调用del时则会触发__del__,并不是程序最后
class Test:
def __init__(self, name):
self.name = name
def __del__(self):
print("触发__del__")
t = Test("python")
print("end")
del t
print("end")
# __len__
class Test:
def __init__(self, name):
self.name = name
def __len__(self):
return len(self.name) # 必须有返回值,且必须为int类型
t = Test("mingming")
print(len(t))
8
# __str__
class Test:
def __init__(self, name):
self.name = name
def __str__(self):
return "hello world" #必须有返回值,且必须为str类型
# 调用方法1
t = Test("mingming")
print(t)
# 调用方法2
print(t.__str__())
hello world
hello world
# __bool__
class Test:
def __init__(self, name):
self.name = name
def __bool__(self):
if self.name =="python": # 返回对象必须是True 或 False
return True
else:
return False
t = Test("python")
t1 = Test("java")
print(bool(t))
print(bool(t1))
True
False
面向对象–私有化
类属性的私有化
- 目的
为了防止外部任意修改公共类属性
私有化的类属性只能够被类方法修改
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知识点 —— Python进阶-2