Python学习笔记Day06~07 - 类

# 普通类的创建方法
# 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)
posted @ 2020-07-04 18:50  Jerome12138  阅读(169)  评论(0编辑  收藏  举报