python基础之 类

本文深入讲解了Python中的类定义、对象概念、类变量与实例变量、继承机制、装饰器的应用以及私有变量和名称改写。通过实例演示了如何创建类、访问属性、继承、装饰器的使用以及技术细节,适合初学者和进阶者阅读。
摘要由CSDN通过智能技术生成

定义:类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用。在 Python 中,类的定义与函数的定义类似,所不同的是,类的定义是使用关键字 “class”。与函数定义相同的是,在定义类时也要使用缩进的形式,以表示缩进的语句属于该类
对象:对象是由类创建出来的一个具体存在,可以直接使用,并且由哪一个类创建出来的对象,就拥有在哪一个类中定义的: 属性和方法。

类的定义语法

最简单的应用: #类中的语句可以是变量(表示类的属性),与可以是函数(表示类的功能)
class ClassName #这里类的命名采用驼峰命名法规则。
<statement-1>
    .
    .
    .
<statement-N>

类对象与实例变量

类变量:定义在类中的,且方法外的变量叫做类变量。除此之外,类变量用于类的所有实例共享的属性和方法,即所有实例共享类变量。
实例变量(对象变量):仅对每一个实例对象独享,且对象之间相互独立。

类变量和实例对象的定义:
class StudentName:
    sex = "男"  这里的sex和score属于对类变量的定义
    score = 100
    def __init__(self,name, age):  
    #这里通过def __init__(self, arg1, arg2) 将所有定义的实例对象定义在—__init__中.
    #        self.attr1 = arg1
    #        self.attr2 = arg2
    #self.attr1和self.attr2就是对象变量,且使用了self。
        self.name = name
        self.age = age
    def print_info(self):  定义类方法
        print("该学生基本信息")
zhangsan = StudentName("zhangsan", 18) #那么这里zhangsan和lisi属于对象的实例化
lisi = StudentName("lisi", 20)
类中的访问:
print(zhangsan.name) #对实例对象的访问
print(zhangsan.sex) #对类对象的访问
print(StudentName.sex) #标准语法是用类名访问类变量
print(zhangsan.score) #此语法为不规范的访问
zhangsan.print_info() #通过实例对象访问类方法
StudentName.print_info(self=zhangsan) #通过类变量访问类方法需要加参数

类的继承

首先明白一点如果不支持继承,语言特性就不值得称为“类”。

类继承的语法:

class ClassName(ParentClass1, ParentClass2, ....):
    <statement-1>
    .
    .
    .
    <statement-N>


#了解”class ClassName(object):“ 这个语句。其实在python中所有的类都默认继承子object, object在继承的语法的时候,可以省略,并且,如果一个类继承自除object之外的类,object是不能写在继承列表中的。
#以下为object以及python内置的函数方法:
def __add__(self, other):
def __sub__(self, other):
def __divmod__(self, other):
def __mul__(self, other):
def __floordiv__(self, other):
def __truediv__(self, other):
def __eq__(self, other):
def __le__(self, other):
def __len__(self):
def __str__(self):
def __repr__(self):
def __dir__(self):
def print_info(self):       
__new__: 创建一个对象
__init__: 初始化一个对象
__add__: 加法:预定的魔法方法
__sub__: 减法:预定义的
__mul__: 乘法:预定义的
__truediv__: 除法:预定义的
__len__:长度
__str__:人可读的的
__repr__:程序员可读的

继承的顺序

python中如何判定继承顺序:__mor__方法
改变类的顺序: 
super(type, object-or-type)
这里type:根据__mro__继承的顺序,从type开始搜寻。
object-or-type:指定我我们对继承顺序,object对应类的__mro__,type对应类的__mro__
super(A, c) => isinstance(c, A) => c是A的一个实例 #判断是否属于类中的实例
super(A, C) => issubclass(C, A) => C是A的一个子类 #判断是否属于类中的子类
例子:
class A:
    def print_info(self):
        print("A")
class B:
    def print_info(self):
        print("B")
    def say_something(self):
        print("B says something")
class C:
    def say_thing(self):
        print("C says something")
class D:
    def print_info(self):
        print("D")
    def say_something(self):
        print("D says something")
class E(A, B, C, D):
    pass
输入:
e = E()   #E类对象的 实例化
print(E.__mro__) #查看E类的继承顺序
e.print_info()  #我们通过对象调用E类中的方法
e.say_something()
结果: #当我们执行上面语句时,可以看出默认执行的是按照E类的执行顺序第一个方法print_info在A类中调用,第二个say_something在B类中调用。
(<class '__main__.E'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
A
B says something
#那么我们怎么改变E的继承顺序呢?
通过以上我们的 super()方法进行。
将我们要改的语句在E类中进行说明。
如: #这里我们将print_info方法调用B类的,将say_something方法调用C类的。
class E(A, B, C, D):
    def print_info(self):
        super(A, self).print_info()  #等价super()print_info()
    def say_something(self):
        super(B, self).say_thing()
结果:#再次运行输入的代码结果如下
B
C says something

装饰器

定义:函数去装饰别的函数,一个函数叫我们的装饰器,一个函数叫做被装饰的函数或者原函数
python中的装饰器:在不改变原函数代码的情况下,增强原函数的功能。
装饰器语法:
1.利用闭包定义一个装饰器
2.利用装饰器的语法糖: @装饰器名, 写在被装饰函数的上边

闭包

定义:一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行,能够读取其他函数内部变量的函数。
闭包特征:
1.嵌套函数
2.内层函数引用了外层函数的变量
3.内层函数作为回值返回给外层函数
自由变量: 既不是局部变量,也不是模块全局变量
在闭包的时候:内层引用外层函数的变量

def outer(fucn):  #fucn是一个自由变量,它指的是我们调用此函数的函数即是test_fucn。
    data = fucn
    def inner():
        print("我们赢了")
        fucn()
        print("EDG NB")
    return inner

@outer
def test_fucn(): 
    print("S11 champion: EDG")
test_fucn()
结果:
我们赢了
S11 champion: EDG
EDG NB
从上面可以看出装饰器并没有传递参数,那么装饰器怎么传递参数呢?
输入:
def outer(func):
    def inner(arg1, arg2):
        print("我们赢啦")
        func(arg1, arg2)
        print("EDG NB")
    return inner

@outer
def test_arg(arg1, arg2):
    print(arg1, arg2)
test_arg(1, 2)
结果:
我们赢啦
1 2
EDG NB

装饰器的委托属性

委托属性:当类中有一个对象变量_x: 但是_x不想让用户直接去访问,但是可以通过其他的方式去操作它。_x ——> 不能 _x = xxx, 不能直接去访问_x,所以可以创建一个委托属性:操作委托属性就相当于操作_x。
静态方法:staticmethod
@staticmethod
类方法: classmethod
@classmethod
调用方法:
# 1.直接使用类名.方法名
# 2.使用对象.方法名
既然类名.方法名可以调用,意味着我在可以不实例化对象的时候调用它。
class Person:

    @staticmethod
    def static_method():
        print("This is static method")

    @classmethod
    def class_method(cls):
        print("This is class method:", cls)
    # cls => class和定义类的时候的关键字冲突,cls
    # cls指向的就是调用它的类
Person.class_method()
Person.static_method()
human = Person()
human.class_method()
human.static_method()
结果:
This is class method: <class '__main__.Person'>
This is static method
This is class method: <class '__main__.Person'>
This is static method
例子2.
class Woman:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self._gender = gender

    def print_info(self):
        print(self.name, self.age, self._gender)

    @property
    def gender(self):
        return self._gender

    @gender.setter
    def gender(self, value):
        self._gender = value

    @gender.deleter
    def gender(self):
        del self._x
用户可以去直接操作name, age,但是不能直接_gender,所以可以给_gender 产生一个委托属性 gender,并且通过操作gender就相当于操作_gender。
操作的方式:访问gender, 修改gender, 删除。
委托属性怎么产生?
我们可以提供一些方法:访问get, 修改方法set, 删除方法del。
使用python中提供装饰器讲这些方法转换成属性
给这些方法起相同名字xxx:具有一个委托属性xxx
_gender的委托属性gender

python中的私有变量

python解释器中的名称改写:
      由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),
      因此存在对此种机制的有限支持,称为名称改写。
名称改写:在类中定义的__xxx的变量和方法, python解释器都会进行名称改写
        改成_ClassName__xxx: 在变量名之前加_ClassName
例子:
class Parent:
    def __method1(self): # __method1 => _Parent__method1
        print("123")

class Son(Parent):
    def __method1(self): # __method1 => _Son__method1
        print("456")
# 子类son从父类继承: _Parent__method1,
# 子类中有两个方法: _Parent__method1, _Son__method1
son = Son()
son._Son__method1()
son._Parent__method1()
结果:
456
123
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值