Python学习笔记Day06~07 - 类
目录
- 类
- 1.构造函数:在实例化时做一些类的初始化工作
- 2.析构函数:在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作,
- 3.实例变量与类变量,类变量是大家共用的属性,能节省内存开销
- 4.静态属性与动态属性,分别表示变量和方法
- 5.私有方法,私有属性,加__,在外部无法调用
- 6.封装
- 7.继承 作用就是减少代码量,子类可以重构父类的方法,可以继承多个父类
- 8.多态 一种接口,多种形态
- 类方法、静态方法和属性方法
- 12.类的特殊成员用法:doc,module,class,dict,call,str,getitem,setitem,delitem
- 13.所有类的数据类型就是type,通过__metaclass__可自定义
类
# 普通类的创建方法
# class Foo(object):
# def __init__(self, name):
# self.name = name
#
#
# f = Foo("alex")
# print(type(f))
# print(type(Foo))
# 类的特殊创建方法
def func(self):
print('hello %s' %self.name)
def __init__(self,name,age):
self.name = name
self.age = age
Foo = type('Foo', (object,), {'func': func,
'__init__':__init__}) # 所有类都是type的实例化
f = Foo("Chrn",22)
f.func()
print(type(Foo))
1.构造函数:在实例化时做一些类的初始化工作
2.析构函数:在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作,
如关闭一些数据库连接,关闭打开的临时文件
3.实例变量与类变量,类变量是大家共用的属性,能节省内存开销
4.静态属性与动态属性,分别表示变量和方法
5.私有方法,私有属性,加__,在外部无法调用
6.封装
7.继承 作用就是减少代码量,子类可以重构父类的方法,可以继承多个父类
py2 经典类是按深度优先来继承的,新式类是按广度优先来继承的
py3 经典类和新式类都是统一按广度优先来继承的
8.多态 一种接口,多种形态
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
pass #raise NotImplementedError("Subclass must implement abstract method")
@staticmethod
def animal_talk(obj):
obj.talk()
class Cat(Animal):
def talk(self):
print('Meow!')
class Dog(Animal):
def talk(self):
print('Woof! Woof!')
d = Dog("陈荣华")
#d.talk()
c = Cat("徐良伟")
#c.talk()
# def animal_talk(obj):
# obj.talk()
Animal.animal_talk(c) # 通过一个接口,按不同的子类实现不同的效果
Animal.animal_talk(d)
类方法、静态方法和属性方法
9.静态方法@staticmethod:不能访问类变量和实例变量,就相当于一个普通函数,与类的其他属性无关
# http://www.cnblogs.com/alex3714/articles/5213184.html
class Dog(object):
# __metaclass__ = MyType #指定该类由谁实例化
# def __new__(cls, *args, **kwargs):
# 类的生成、调用、顺序依次是:__new__ --> __init__ --> __call__
n = 123 # 类变量,可被实例变量覆盖
def __init__(self, name):
self.name = name # 实例变量(静态属性),作用域是实例本身
# @classmethod # 类方法:只能访问类变量,不能访问实例变量
# @staticmethod # 静态方法:不能访问类变量和实例变量,就相当于一个普通函数,与类的其他属性无关
# @property # 属性方法:调用不需要加括号,也不能传参数
def eat(self): #类的方法(动态属性)
print('%s is eatting...' % self.name)
def __call__(self, *args, **kwargs):
print('实例对象后面加括号触发') # 用d()调用
def __str__(self):
return "打印实例对象时输出返回的值" # 用d 调用
def __getitem__(self, item):
print('索引获取,如字典')
# 实例:key_value
# result = obj['k1'] # 自动触发执行 __getitem__
# obj['k2'] = 'alex' # 自动触发执行 __setitem__
# del obj['k1'] # 自动触发执行 __setitem__
def __setitem__(self, key, value):
print('索引设置')
def __delitem__(self, key):
print('索引删除')
d = Dog('金毛') #实例化
d.bullet_prove = True #添加实例变量
del d.name #删除实例的变量
d.n = '改变类变量' #相当于添加一个实例变量,原本的类变量并没有改变
#类的特殊成员方法
d.__doc__ #输出类的描述信息
d.__module__ #输出类所属模块lib
d.__class__ #输出类所属类
d.__dict__ #查看实例中的所有变量
Dog.__dict__ #查看类中的所有成员
10.类方法@classmethod:只能访问类变量,不能访问实例变量
11.属性方法@property:把一个方法变成一个静态属性,调用不需要加括号,也不能传参数
要给属性方法传参数只能使用.setter再写一个同名方法
接口,对用户来讲,只需要属性的结果,不需要知道其中的过程
class Flight(object):
def __init__(self,name):
self.flight_name = name
def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 0
@property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later")
@flight_status.setter
def flight_status(self,status):
print("flight %s has changed status to %s" %(self.flight_name,status))
f = Flight("CA980")
f.flight_status
f.flight_status = 2
12.类的特殊成员用法:doc,module,class,dict,call,str,getitem,setitem,delitem
# hasattr(obj,name_str) , 判断一个对象obj里是否有对应的name_str字符串的方法
# getattr(obj,name_str), 根据字符串去获取obj对象里的对应的方法的内存地址
# setattr(obj,'y',z), is equivalent to ``obj.y = z''
# delattr(obj,z)
def bulk(self):
print("%s is yelling...." % self.name)
class Dog(object):
def __init__(self, name):
self.name = name
def eat(self, food):
print("%s is eating..." % self.name, food)
d = Dog("NiuHanYang")
choice = input(">>:").strip()
if hasattr(d, choice): # 判断实例是否有这个方法
getattr(d, choice) # 获得实例中的方法
else:
setattr(d, choice, bulk) # d.talk = bulk 为实例添加方法
func = getattr(d, choice)
func(d)
13.所有类的数据类型就是type,通过__metaclass__可自定义
类的创建过程
class MyType(type):
def __init__(self, what, bases=None, dict=None): # 创建类时执行的第一阶段
print("--MyType init---")
super(MyType, self).__init__(what, bases, dict)
def __call__(self, *args, **kwargs): # 创建实例时执行的第二阶段第一步
print("--MyType call---")
obj = self.__new__(self, *args, **kwargs)
obj.data = {"name":111}
self.__init__(obj, *args, **kwargs)
class Foo(object):
__metaclass__ = MyType # 定制类的创建过程,默认type
def __init__(self, name): # 创建实例时执行的第二阶段第三步
self.name = name
print("Foo ---init__")
def __new__(cls, *args, **kwargs): # 类自带,用来创建实例,先于__init__执行,第二阶段第二步
print("Foo --new--")
#print(object.__new__(cls))
return object.__new__(cls) # 继承父类的__new__方法 #cls相当于类的self
# 第一阶段:解释器从上到下执行代码创建Foo类,执行MyType的__init__方法
# 第二阶段:通过Foo类创建obj对象 __call__,__new__,__init__
obj = Foo("Alex")
print(obj.name)