一.属性
1.1 类属性
代码:
class A():
name='jack' #公有的类属性
__age=18 #私有的类属性
a=A() #实例对象
print(a.name) #jack
print(A.name) #jack
print(a.__age) #AttributeError
print(A.__age) #AttributeError
总结:
(1) 实例对象和类可以调用类属性
(2) 私有的类属性只不能通过实例对象和类调用
1.2 实例属性
代码:
class B():
def __init__(self):
self.name='jack' #实例属性公有
self.__age=18 #实例属性私有
b=B() #实例对象
print(b.name) #jack
print(b.__age) #AttributeError
print(B.name) #AttributeError
print(B.__age) #AttributeError
总结:
(1) 实例属性可以通过实例对象调用,类不能调用
(2) 私有的实例属性不能通过实例对象和类调用
1.3通过实例对象修改类属性
代码:
class B():
country='china' #类属性
#实例对象
p1=B()
#通过实例对象调用类属性
print(p1.country)
#通过类调用类属性
print(B.country)
# 通过实例对象修改类属性
p1.country='Japan'
print(p1.country)
p2=B()
print(p2.country)
返回值:
china
china
Japan
china
总结:
通过实例对象修改类属性,只对本对象有效果,对其他对象没有效果
二.方法
2.1 类方法
代码:
class People():
#类属性
age=18
# 类方法,通过classmethod进行标识
@classmethod
def get_age(cls): #get_xxx 用来获取数据
return cls.age
p=People() #实例对象
# 通过实例对象访问类方法
print(p.get_age()) #返回值:18
# 通过类访问类方法
print(People.get_age()) #返回值:18
总结:
(1) 类方法需要用修饰器@classmethob进行标识
(2) 对于类方法,第一个参数代表类对象,一般以cls作为第一个参数(也可以用其他名称代替)
(3) 可以通过实例对象和类对象引用类方法
扩展: 类方法还有一个用途就是可以对类属性进行修改
代码:
class People(object):
# 类属性
age= 18
#类方法,用@classmethod来进行修饰
@classmethod
def get_country(cls): #返回数据
return cls.age
@classmethod
def set_country(cls,age): #接收参数,修改数据
cls.age = age
#实例化对象
p = People()
#可以用过实例对象访问
print(p.get_country()) #返回值:18
#可以通过类访问
print(People.get_country()) #返回值:18
#修改数据
p.set_country(23)
print(p.get_country()) #返回值:23
print(People.get_country()) #返回值:23
#实例化对象
p1 = People()
print(p1.get_country()) #返回值:23
总结:
使用类方法修改类属性之后,通过实例对象和类调用类方法都发生了改变
2.2 静态方法
代码:
class People():
#类属性
age=18
# 静态方法, 通过@staticmethod进行修饰
@staticmethod
def get_ages():
return People.age
p=People()
# 通过实例对象访问静态方法
print(p.get_ages()) #返回值:18
# 通过类访问静态方法
print(People.get_ages()) #返回值:18
总结:
(1)静态方法需要用@staticmethod进行修饰
(2)在静态方法中引用类属性的话,必须通过类实例对象来引用
(3)可以通过实例对象和类调用静态方法
2.3 实例方法
代码:
class People():
age=18
# 实例方法
def get_agess(self):
return self.age
p=People()
# 通过实例对象访问实例方法
print(p.get_agess()) #返回值:18
# 通过类访问实例方法
# print(People.get_agess()) #TypeError
总结:
只能通过实例对象调用实例方法
2.4 new方法
代码:
class C():
def __init__(self):
print('这是init方法')
def __new__(cls,*args,**kwargs):
print('这是new方法')
return object.__new__(cls)
c=C()
返回结果:
这是new方法
这是init方法
总结:
(1) __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器提供
(2) __new__必须要有返回值,返回实例化出来的实例.可以return父类__new__出来的实例或直接是object的
__new__出来的实例
(3) __init__中的self参数就是__new__返回的实例
注意:
class D():
def __init__(self):
print('*'*20)
print(self)
print('这是init方法')
def __new__(cls,*args,**kwargs):
print(id(cls))
print('这是new方法')
s=object.__new__(cls)
print(s)
return s
d=D()
返回结果:
2973344023056
这是new方法
<__main__.D object at 0x000002B449773A00>
********************
<__main__.D object at 0x000002B449773A00>
这是init方法
2.5 单例模式
单例模式: 永远使用一个对象得实例(只有一个id)
代码:
class Foo(object):
instance = None
def __init__(self):
self.name = 'alex'
def __new__(cls):
if Foo.instance:
return Foo.instance
else:
Foo.instance = object.__new__(cls)
return Foo.instance
obj1 = Foo()
obj2 = Foo()
print(obj1)
print(obj2)
返回结果:
<__main__.Foo object at 0x000001F3BD733A00>
<__main__.Foo object at 0x000001F3BD733A00>