一.类结构、类属性、类方法
1.类的结构
在python中使用面向对象进行开发,首先就是设计类;使用类名()创建对象时,创建对象的动作为(1.在内存中为对象分配空间;2.调用初始化方法对 对象进行初始化);当对象创建成功后,内存中就有了一个对象实实在在的存在即为实例。
所以:
创建出来的对象叫做类的实例;创建的对象的动作叫做示例化;对象调用的方法叫做实例方法
在程序执行的过程中:
每个对象均拥有自己的专一属性;当调用对象方法,可以通过使用self访问自己的属性,调用自己的方法
由此可知:
每一个对象都有自己独立的内存空间,保存各自不同的属性;多个对象的方法在内存中只有一份,则在调用方法时,需要把对象的引用传递到方法的内部
2.类属性
针对类对象定义的属性,使用赋值语句在class关键字下可以定义类的属性
3.类方法
针对类对象定义的方法,在类方法内部可以直接访问类属性或者调用其他的类方法
class Toy(object):
#使用赋值语句直接定义类属性
count = 0
def __init__(self,name):
self.name = name
#类属性+1
Toy.count += 1
@classmethod
def show_toy_count(cls):
# 直接访问类属性
print('玩具的数量为%d' %(cls.count))
toy1 = Toy('泰迪熊')
toy2 = Toy('唐老鸭')
#调用类方法
Toy.show_toy_count()
玩具的数量为2
@classmethod是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。 类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 对于类方法,可以通过类来调用,就像C.f()
二.静态方法
不需要创建对象就可以直接引用
在开发时,如果需要在类中定义一个方法,这个方法,既不需要访问实例属性也不需要调用实例方法;既不需要访问类属性也不需要调用类方法,这个时候就可以把这个方法封装成静态方法。
class Cat(object):
@staticmethod
def call():
print('喵~')
#通过类名来调用静态方法
Cat.call()
喵~
三.私有属性和私有方法
1.应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象的内部使用,而不希望在外部被访问到
私有属性:就是对象不希望公开的属性
私有方法:就是方法不希望公开的方法
2.定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
3.特征
子类对象不能在自己的方法内部,直接访问父类的私有属性和私有方法
子类对象可以通过父类的公有方法间接访问到私有属性或私有方法
私有属性,私有方法是对象的隐私,不对外公开,外界以及子类都不能直接访问
私有属性,私有方法常用做一些内部的事情
class Student(object):
def __init__(self,name,score):
# 定义两个私有属性,外部不可以随便的更改和访问
self.__name = name
self.__score = score
def get_grand(self):
print('my name is %s,my grade is %d' %(self.__name,self.__score))
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_name(self,name):
if isinstance(name,str):
self.__name = name
else:
raise ValueError('请输入正确的名字')
def set_score(self,score):
if isinstance(score,int):
self.__score = score
else:
raise ValueError('请输入正确的成绩')
tom = Student('Tom',90)
tom.get_grand()
# 修改私有属性变量
tom.set_name('Luck')
tom.set_score(96)
tom.get_grand()
print(tom.get_name())
print(tom.get_score())
my name is Tom,my grade is 90
my name is Luck,my grade is 96
Luck
96
当外部直接访问对象的私有属性时会报错,不能够直接访问
tom = Student('Tom',90)
print(tom.name)
print(tom.score)
tom.get_grand()
File "/home/kiosk/PycharmProjects/untitled/0530/6.13/01.py", line 231, in <module>
print(tom.__name)
AttributeError: 'Student' object has no attribute '__name'
四.python中的设计模式
1.设计模式是什么
设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一特定问题的成熟解决方案
使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性
2.单例设计模式
目的
让类创建对象,在系统中只有唯一的一个实例;每一次去执行类名()返回的对象时,内存地址都是相同的
3.如何保证单例设计模式中,对象只有一个
利用__new__方法实现对象只有一个
是一个由object基类提供的内置的静态方法,主要有两个作用:在内存中为对象分配空间;返回对象的引用
我们用 类名. 的方式创建对象的时候,python解释器会帮我们做两件事情:为对象分配空间 ;对象初始化
使用类名()创建对象时,python的解释器首先会调用__new__方法为对象分配空间
python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法
我们要重写new方法,使用类名()创建对象的时候,返回的都是同一个地址
重写__new__方法的代码非常固定:
继承自父类方法
返回父类方法调用_new__方法的结果
重写__new__方法一定要return object.new(cls),否则python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法
class MusicPlayer(object):
instance = None
def __new__(cls, *args, **kwargs):
print('创建对象 分配空间')
# 判断类属性是否是空对象
if cls.instance is None:
# 调用父类方法 为第一个对象分配空间
cls.instance = object.__new__(cls) ##创建新对象,调用__new__方法
return cls.instance ##此时返回的是对象的引用
player1 = MusicPlayer()
player2 = MusicPlayer()
player3 = MusicPlayer()
print(player1)
print(player2)
print(player3)
创建对象 分配空间
创建对象 分配空间
创建对象 分配空间
<__main__.MusicPlayer object at 0x7f380246f278> ##有此可知,每一次执行类对象,返回的内存地址都是相同的
<__main__.MusicPlayer object at 0x7f380246f278>
<__main__.MusicPlayer object at 0x7f380246f278>