1、类

1.1 类的定义

# 类的定义
    class 类名:
        pass    # pass是空语句,不具有任何意义,仅为了保持程序结构完整性

# 创建对象
    对象名 = 类名()
# 类的定义
    class 类名:
        pass    # pass是空语句,不具有任何意义,仅为了保持程序结构完整性

# 创建对象
    对象名 = 类名()

1.2 成员变量

# 成员变量用于描述对象的固有状态或属性。
# 成员变量定义语法
class 类名:
    def __init__(self):
        # 公有属性
        self.变量名1 = 值1      
        self.变量名2 = None
        
对象名.变量名 = 值     # 独有属性

class Person:
    def __init__(self):
        self.name = None
        self.age = 22

p1 = Person()
p1.name = "Tom"
p1.ID = 123456
print(p1.name)
print(p1.age)
print(p1.ID)

"""
公有变量与独有变量的区别
    公有变量在__init__方法中声明,每个对象都具有该变量
    独有变量在创建对象后声明,只有当前对象具有此变量
    定义对象的独有变量时,如果独有变量名与公有变量名相同,视为修改公有变量的值;如果独有变量名与公有变量名不相同,视为定义新的独有属性
    None含义是为空,表示没有具体的数据
"""
# 成员变量用于描述对象的固有状态或属性。
# 成员变量定义语法
class 类名:
    def __init__(self):
        # 公有属性
        self.变量名1 = 值1      
        self.变量名2 = None
        
对象名.变量名 = 值     # 独有属性

class Person:
    def __init__(self):
        self.name = None
        self.age = 22

p1 = Person()
p1.name = "Tom"
p1.ID = 123456
print(p1.name)
print(p1.age)
print(p1.ID)

"""
公有变量与独有变量的区别
    公有变量在__init__方法中声明,每个对象都具有该变量
    独有变量在创建对象后声明,只有当前对象具有此变量
    定义对象的独有变量时,如果独有变量名与公有变量名相同,视为修改公有变量的值;如果独有变量名与公有变量名不相同,视为定义新的独有属性
    None含义是为空,表示没有具体的数据
"""

1.3 成员方法

# 成员方法用于描述对象的固有行为
# 定义成员方法
格式一(无参方法):
class 类名:        
    def 方法名(self):
        方法体
        
class Cat:        
    def eat(self):
        print("猫吃鱼")
        
格式二(有参方法)
class 类名:        
    def 方法名(self,形参1,形参2,…):
        方法体
        
class Cat:     
    def climb(self,meter):
        print("猫会爬树,爬了%d米" % meter)

# 调用成员方法
格式一(调用无参方法): 
    对象名.方法名()

格式二(调用有参方法): 
    对象名.方法名(实参1,实参2,…)
    
# 成员方法中调用成员变量语法:self.变量名
# 成员方法中调用成员方法语法:self.方法名(实参1,实参2,…)
# self仅出现在成员方法中,指代执行该方法的对象。
# 成员方法用于描述对象的固有行为
# 定义成员方法
格式一(无参方法):
class 类名:        
    def 方法名(self):
        方法体
        
class Cat:        
    def eat(self):
        print("猫吃鱼")
        
格式二(有参方法)
class 类名:        
    def 方法名(self,形参1,形参2,…):
        方法体
        
class Cat:     
    def climb(self,meter):
        print("猫会爬树,爬了%d米" % meter)

# 调用成员方法
格式一(调用无参方法): 
    对象名.方法名()

格式二(调用有参方法): 
    对象名.方法名(实参1,实参2,…)
    
# 成员方法中调用成员变量语法:self.变量名
# 成员方法中调用成员方法语法:self.方法名(实参1,实参2,…)
# self仅出现在成员方法中,指代执行该方法的对象。

1.4 类变量

# 概念:类变量是定义在类中,不属于某个具体对象的特征,被所有对象共同使用的特征;类变量可以私有化
# 定义类变量语法格式
    class 类名:
        变量名 = 值
        
# 调用类变量语法格式
# 赋值格式:
    类名.类变量名 = 值
# 取值格式:
    类名.类变量名(推荐)
    对象名.类变量名(不推荐)
    
class Student:
    Class = 132251      # 类变量
    __num = None        # 类变量可以私有化
    def info(self):
        self.name = None
        self.__score = None
        self.__IDcard = None

    def set_info(self, s_score, s_IDcard):
        self.__score = s_score
        self.__IDcard = s_IDcard

    def get_info(self):
        return self.__score, self.__IDcard

    
stu = Student()
stu.Class = 132252       # 可通过stu.__class__.Class = xxx 修改,可通过类方法修改
stu.name = input("name = ")
stu.set_info(99, 13225223)
x, y = stu.get_info()
print("Class = %d Name = %s IDcard = %d Score = %d" % (Student.Class, stu.name, y, x))  
# 概念:类变量是定义在类中,不属于某个具体对象的特征,被所有对象共同使用的特征;类变量可以私有化
# 定义类变量语法格式
    class 类名:
        变量名 = 值
        
# 调用类变量语法格式
# 赋值格式:
    类名.类变量名 = 值
# 取值格式:
    类名.类变量名(推荐)
    对象名.类变量名(不推荐)
    
class Student:
    Class = 132251      # 类变量
    __num = None        # 类变量可以私有化
    def info(self):
        self.name = None
        self.__score = None
        self.__IDcard = None

    def set_info(self, s_score, s_IDcard):
        self.__score = s_score
        self.__IDcard = s_IDcard

    def get_info(self):
        return self.__score, self.__IDcard

    
stu = Student()
stu.Class = 132252       # 可通过stu.__class__.Class = xxx 修改,可通过类方法修改
stu.name = input("name = ")
stu.set_info(99, 13225223)
x, y = stu.get_info()
print("Class = %d Name = %s IDcard = %d Score = %d" % (Student.Class, stu.name, y, x))

1.5 类方法

# 概念:类方法是定义在类中,不属于某个具体对象的行为,被所有对象共同使用的行为
# 定义类方法基本语法:
class 类名:
    @classmethod
    def 方法名(cls, 形参1,形参2,…):
        方法体
        
# 调用类方法语法格式
    类名.类方法名(实参1,实参2,…)   (推荐)
    对象名.类方法名(实参1,实参2,…) (不推荐)
    
    
    Class = 132252
    def __init__(self):
        self.name = None
        self.score = None

    @classmethod
    def m_Print(cls):
        Student.score = 95
        print(Student.score)
        print(Student.Class)
        print("aaa")


stu = Student()
stu.name = "Tom"
Student.m_Print()
print(stu.name)    
# 概念:类方法是定义在类中,不属于某个具体对象的行为,被所有对象共同使用的行为
# 定义类方法基本语法:
class 类名:
    @classmethod
    def 方法名(cls, 形参1,形参2,…):
        方法体
        
# 调用类方法语法格式
    类名.类方法名(实参1,实参2,…)   (推荐)
    对象名.类方法名(实参1,实参2,…) (不推荐)
    
    
    Class = 132252
    def __init__(self):
        self.name = None
        self.score = None

    @classmethod
    def m_Print(cls):
        Student.score = 95
        print(Student.score)
        print(Student.Class)
        print("aaa")


stu = Student()
stu.name = "Tom"
Student.m_Print()
print(stu.name)

1.6 静态方法

# 定义静态方法语法格式
class 类名:
    @staticmethod
        def 方法名(形参1,形参2,…):
            方法体

# 调用静态方法语法格式
    类名.静态方法名(实参1,实参2,…)  (推荐)
    对象名.静态方法名(实参1,实参2,…) (不推荐)

各种方法定义规则
    只访问成员变量的方法,定义成实例方法
    只访问类变量的方法,定义类方法
    既访问成员变量,也访问类变量的方法,定义成实例方法
    既不访问成员变量,也不访问类变量,定义成静态方法
# 定义静态方法语法格式
class 类名:
    @staticmethod
        def 方法名(形参1,形参2,…):
            方法体

# 调用静态方法语法格式
    类名.静态方法名(实参1,实参2,…)  (推荐)
    对象名.静态方法名(实参1,实参2,…) (不推荐)

各种方法定义规则
    只访问成员变量的方法,定义成实例方法
    只访问类变量的方法,定义类方法
    既访问成员变量,也访问类变量的方法,定义成实例方法
    既不访问成员变量,也不访问类变量,定义成静态方法

1.7 __init__方法

# __init__方法,也称为构造方法,创建对象时为对象初始化成员变量
定义语法
格式一:
def __init__(self):
    self.变量名1 = 值1
格式二:
def __init__(self,形参1,形参2,…):
    self.__属性名1 = 形参1
    self.__属性名2 = 形参2
# __init__方法,也称为构造方法,创建对象时为对象初始化成员变量
定义语法
格式一:
def __init__(self):
    self.变量名1 = 值1
格式二:
def __init__(self,形参1,形参2,…):
    self.__属性名1 = 形参1
    self.__属性名2 = 形参2

1.8 __str__方法

# __str__方法是在使用print函数打印输出对象到屏幕时被调用的方法,用于返回对象的规范化字符串表现形式
def __str__(self):
    return 打印对象是显示的信息

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "name = %s, age = %d" % (self.name, self.age)


p1 = Person("Tom",22)
print(p1)
# __str__方法是在使用print函数打印输出对象到屏幕时被调用的方法,用于返回对象的规范化字符串表现形式
def __str__(self):
    return 打印对象是显示的信息

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "name = %s, age = %d" % (self.name, self.age)


p1 = Person("Tom",22)
print(p1)

1.9 property

  • 一种用起来像是使用的实例属性一样的特殊属性,可以对应于某个方法
  • property属性的定义和调用要注意一下几点:
  • 定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数
  • 调用时,无需括号
方法:foo_obj.func()
property属性:foo_obj.prop


class Pager:
    def __init__(self, current_page):
        # 用户当前请求的页码(第一页、第二页...)
        self.current_page = current_page
        # 每页默认显示10条数据
        self.per_items = 10 

    @property
    def start(self):
        val = (self.current_page - 1) * self.per_items
        return val

    @property
    def end(self):
        val = self.current_page * self.per_items
        return val

################ 调用 ###############
p = Pager(1)
p.start  # 就是起始值,即:m
p.end  # 就是结束值,即:n
方法:foo_obj.func()
property属性:foo_obj.prop


class Pager:
    def __init__(self, current_page):
        # 用户当前请求的页码(第一页、第二页...)
        self.current_page = current_page
        # 每页默认显示10条数据
        self.per_items = 10 

    @property
    def start(self):
        val = (self.current_page - 1) * self.per_items
        return val

    @property
    def end(self):
        val = self.current_page * self.per_items
        return val

################ 调用 ###############
p = Pager(1)
p.start  # 就是起始值,即:m
p.end  # 就是结束值,即:n
  • Python的property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回
  • property属性的有两种方式
  • 装饰器 即:在方法上应用装饰器
# 经典类
class Goods:
    @property
    def price(self):
        return "laowang"

obj = Goods()
result = obj.price  # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
print(result)

# 新式类
class Goods:
    """python3中默认继承object类
        以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter  @xxx.deleter
    """
    @property
    def price(self):
        print('@property')

    @price.setter
    def price(self, value):
        print('@price.setter')

    @price.deleter
    def price(self):
        print('@price.deleter')


obj = Goods()
obj.price          # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123    # 自动执行 @price.setter 修饰的 price 方法,并将  123 赋值给方法的参数
del obj.price      # 自动执行 @price.deleter 修饰的 price 方法


经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
# 经典类
class Goods:
    @property
    def price(self):
        return "laowang"

obj = Goods()
result = obj.price  # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
print(result)

# 新式类
class Goods:
    """python3中默认继承object类
        以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter  @xxx.deleter
    """
    @property
    def price(self):
        print('@property')

    @price.setter
    def price(self, value):
        print('@price.setter')

    @price.deleter
    def price(self):
        print('@price.deleter')


obj = Goods()
obj.price          # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123    # 自动执行 @price.setter 修饰的 price 方法,并将  123 赋值给方法的参数
del obj.price      # 自动执行 @price.deleter 修饰的 price 方法


经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
  • 类属性 即:在类中定义值为property对象的类属性
当使用类属性的方式创建property属性时,经典类和新式类无区别


class Foo(object):
    def get_bar(self):
        print("getter...")
        return 'laowang'

    def set_bar(self, value): 
        """必须两个参数"""
        print("setter...")
        return 'set value' + value

    def del_bar(self):
        print("deleter...")
        return 'laowang'

    BAR = property(get_bar, set_bar, del_bar, "description...")

obj = Foo()

obj.BAR  # 自动调用第一个参数中定义的方法:get_bar
obj.BAR = "alex"  # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
desc = Foo.BAR.__doc__  # 自动获取第四个参数中设置的值:description...
print(desc)
del obj.BAR  # 自动调用第三个参数中定义的方法:del_bar方法


property方法中有个四个参数
  第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
  第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

由于类属性方式创建property属性具有3种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
当使用类属性的方式创建property属性时,经典类和新式类无区别


class Foo(object):
    def get_bar(self):
        print("getter...")
        return 'laowang'

    def set_bar(self, value): 
        """必须两个参数"""
        print("setter...")
        return 'set value' + value

    def del_bar(self):
        print("deleter...")
        return 'laowang'

    BAR = property(get_bar, set_bar, del_bar, "description...")

obj = Foo()

obj.BAR  # 自动调用第一个参数中定义的方法:get_bar
obj.BAR = "alex"  # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
desc = Foo.BAR.__doc__  # 自动获取第四个参数中设置的值:description...
print(desc)
del obj.BAR  # 自动调用第三个参数中定义的方法:del_bar方法


property方法中有个四个参数
  第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
  第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

由于类属性方式创建property属性具有3种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

1.10 魔法属性

  • __doc__ : 表示类的描述信息
class Foo:
    """ 描述类信息,这是用于看片的神奇 """
    def func(self):
        pass

print(Foo.__doc__)
#输出:类的描述信息
class Foo:
    """ 描述类信息,这是用于看片的神奇 """
    def func(self):
        pass

print(Foo.__doc__)
#输出:类的描述信息
  • __module__ : 表示当前操作的对象在哪个模块
class Person(object):
    def __init__(self):
        self.name = 'laowang'

obj = Person()
print(obj.__module__)  # 输出 test 即:输出模块
print(obj.__class__)
class Person(object):
    def __init__(self):
        self.name = 'laowang'

obj = Person()
print(obj.__module__)  # 输出 test 即:输出模块
print(obj.__class__)
  • __class__ : 表示当前操作的对象的类是什么
  • __del__ : 当对象在内存中被释放时,自动触发执行,此方法一般无须定义
class Foo:
    def __del__(self):
        pass
class Foo:
    def __del__(self):
        pass
  • __call__ : 对象后面加括号,触发执行
注:__init__方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__')


obj = Foo()  # 执行 __init__
obj()  # 执行 __call__
注:__init__方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__')


obj = Foo()  # 执行 __init__
obj()  # 执行 __call__
  • __dict__ : 类或对象中的所有属性
类的实例属性属于对象;类中的类属性和方法等属于类
class Province(object):
    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print('func')

# 获取类的属性,即:类属性、方法、
print(Province.__dict__)

obj1 = Province('山东', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 10000, 'name': '山东'}

obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 20000, 'name': '山西'}
类的实例属性属于对象;类中的类属性和方法等属于类
class Province(object):
    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print('func')

# 获取类的属性,即:类属性、方法、
print(Province.__dict__)

obj1 = Province('山东', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 10000, 'name': '山东'}

obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 20000, 'name': '山西'}
  • __getitem__、__setitem__、__delitem__
# 用于索引操作,如字典。以上分别表示获取、设置、删除数据
class Foo(object):

    def __getitem__(self, key):
        print('__getitem__', key)

    def __setitem__(self, key, value):
        print('__setitem__', key, value)

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'laowang'   # 自动触发执行 __setitem__
del obj['k1']           # 自动触发执行 __delitem__
# 用于索引操作,如字典。以上分别表示获取、设置、删除数据
class Foo(object):

    def __getitem__(self, key):
        print('__getitem__', key)

    def __setitem__(self, key, value):
        print('__setitem__', key, value)

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'laowang'   # 自动触发执行 __setitem__
del obj['k1']           # 自动触发执行 __delitem__
  • __getslice__、__setslice__、__delslice__
# 该三个方法用于分片操作,如:列表
class Foo(object):

    def __getslice__(self, i, j):
        print('__getslice__', i, j)

    def __setslice__(self, i, j, sequence):
        print('__setslice__', i, j)

    def __delslice__(self, i, j):
        print('__delslice__', i, j)

obj = Foo()

obj[-1:1]                   # 自动触发执行 __getslice__
obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
del obj[0:2]                # 自动触发执行 __delslice__

# 切片可对该类实例化出的对象的原数据进行设置、修改、删除
# 该三个方法用于分片操作,如:列表
class Foo(object):

    def __getslice__(self, i, j):
        print('__getslice__', i, j)

    def __setslice__(self, i, j, sequence):
        print('__setslice__', i, j)

    def __delslice__(self, i, j):
        print('__delslice__', i, j)

obj = Foo()

obj[-1:1]                   # 自动触发执行 __getslice__
obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
del obj[0:2]                # 自动触发执行 __delslice__

# 切片可对该类实例化出的对象的原数据进行设置、修改、删除