Consolidations for some python common concepts


Python是面向对象的一种高级语言,一切皆对象是python的基本宗旨,学习面向对象的语言,有几个重要的概念不得不掌握,不仅是因为这些基本概念是面向对象语言的基石,而且还是检验我们是否能熟练掌握一门编程语言的检验标准,那么具体有哪些相关的概念呢?我想不外乎这些-类,对象,继承,多态,封装,属性和方法等。这篇文章大致总结了一些这些基本概念的基本用法,权当是对我学习的一个回顾吧 -

1. 面向对象的基本概念

(1)类:用来描述具有相同的属性和方法的对象的集合。
(2)对象:通过类定义的数据结构实例

2. 面向对象语言的基本特性

(1)继承:子类完全继承父类的字段和方法。
(2)多态:对不同类型的变量进行相同操作,然后根据对象类型的不同表现出不同的结果。
(3)封装性:将抽象的得到的数据和功能相结合,形成一个类;封装是为了增强安全性和简化编程。

3. 如何理解这些,请看下面的代码实例(注意注释部分!) -

# 类中的函数称为方法,使用方式和一般的函数一样
# 类中的变量也称为类的属性
print(" -#2- ****************************************************************************************************")
class A(object):
    def __init__(self):
        self.num = 1

    def info_print(self):
        print(self.num)

result = A() # 创建对象result,这是实例化类的一种写法,()不能少,不然就是变量A了
result.info_print()

class B(A):
    pass
result = B()
result.info_print()
# Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法


class Master: # 1. 师傅类
    def __init__(self): # self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
        self.kongfu = '[星巴克的摩卡配方]'

    def make_coffee(self):
        print(f'运用{self.kongfu}制作咖啡')
        # 以 f 开头表示在字符串内支持大括号内的python表达式
        # 以 r 开头表示去除字符串中的转义字符
        # 以 b 开头表示后面字符串是bytes 类型
        # 以 u 开头表示后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码
result = Master()
result.make_coffee()

class Prentice(Master): # 2. 徒弟类
    pass

daqiu = Prentice()
print(daqiu.kongfu) # 对象访问实例属性
daqiu.make_coffee() # 对象调用实例方法
# 以上为单继承
# 由此可见,python3创建类的时候,可以不带括号,也可以带,也可以显示继承object,如果带个()空括号,其实也是隐式的继承了object。这三种方式是相等的


print("\n -3- ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '星巴克的摩卡配方'

    def make_coffee(self):
        print(f'运用{self.kongfu}制作咖啡。。。')

class School(object):
    # pass
    def __init__(self):
        self.kongfu = '学校的摩卡咖啡配方'

    def make_coffee(self):
        print(f'运用{self.kongfu}来制作咖啡!!!')

class Prentice(School, Master):
    pass

daqiu = Prentice() # 实例化对象时类名后需要加上()
print(daqiu.kongfu)
daqiu.make_coffee()
# 注意:当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法。默认取最快一个匹配的那一个

print("\n - 4 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '师傅的咖啡制作配方'

    def make_coffee(self):
        print(f'用{self.kongfu}制作咖啡。')

class School(object):
    def __init__(self):
        self.kongfu = '学校教的咖啡制作配方'

    def make_coffee(self):
        print(f'用{self.kongfu}制作一杯咖啡~')

class Prentice(School, Master):
    def __init__(self):
        self.kongfu = 'My own recipe for making coffee'

    def make_coffee(self):
        print(f'Make a cup of coffee with {self.kongfu} @@')

result = Prentice()
result.make_coffee()
print(result.kongfu)
# 子类和父类具有同名属性和方法,默认使用子类的同名属性和方法。

print("\n - 5 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = 'the recipe from Master'

    def make_coffee(self):
        print(f'Make a cup of cofee by {self.kongfu} !')

class School(object):
    def __init__(self):
        self.kongfu = 'the recipe from School'

    def make_coffee(self):
        print(f'Make a cup of cofee by {self.kongfu} @')

class Prentice(Master, School):
    def __init__(self): # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.kongfu = 'the recipe from my original method'

    def make_coffee(self):
        # self.__init__()
        print(f'make a cup of cofee by {self.kongfu} #')

    def make_master_coffee(self): # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
        Master.__init__(self)
        Master.make_coffee(self)

    def make_school_coffee(self): # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
        School.__init__(self)
        School.make_coffee(self)

result = Prentice()
result.make_coffee()
result.make_master_coffee()
result.make_school_coffee()
result.make_coffee()

print("\n - 6 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '师傅的配方!'

    def make_coffee(self):
        print(f'使用{self.kongfu}制作一杯咖啡!')

class School(object):
    def __init__(self):
        self.kongfu = '学校教的配方@'

    def make_coffee(self):
        print(f'使用{self.kongfu}来制作一杯咖啡@')

class Prentice(School, Master):
    def __init__(self):
        self.kongfu = 'my own recipe for coffee.'

    def make_coffee(self):
        self.__init__()
        print(f'make a cup of coffeee with {self.kongfu}.')

    def make_master_coffee(self):
        Master.__init__(self)
        Master.make_coffee(self)

    def make_school_coffee(self):
        School.__init__(self)
        School.make_coffee(self)

# 徒孙类
class Tusun(Prentice):
    pass

result = Tusun()
result.make_coffee()
result.make_school_coffee()
result.make_master_coffee()
# 多层继承关系,Prentice继承Master,School,Tusun又继承Prentice,这是多层继承的一种体现


print("\n - 7 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '师傅的配方!'

    def make_coffee(self):
        print(f'使用{self.kongfu}制作一杯咖啡!')


class School(Master):
    def __init__(self):
        self.kongfu = r"Alan's recipe"

    def make_coffee(self):
        print(f'Using {self.kongfu} to make a cup of coffee.')

        # 方式 一
        super(School, self).__init__()
        super(School, self).make_coffee()

        # 方式 二
        super().__init__()
        super().make_coffee()


result = School()
result.make_coffee()
# 使用super() 可以自动查找父类。调用顺序遵循 __mro__ 类属性的顺序。比较适合单继承使用。


print("\n - 8 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '[师傅教的制作煎饼的方法]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作经典葱油饼')


class School(object):
    def __init__(self):
        self.kongfu = '[小乐经典葱油饼配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作经典葱油饼')


class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创经典葱油饼配方]'
        # 定义私有属性, 设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
        self.__money = 2000000

    # 定义私有方法, 设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
    def __info_print(self):
        print(self.kongfu)
        print(self.__money)

    def make_cake(self):
        self.__init__()
        print(f'运用{self.kongfu}制作经典葱油饼')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

# 徒孙类
class Tusun(Prentice):
    pass

daqiu = Prentice()
# 对象不能访问私有属性和私有方法, 注意这里说的是对象,即对象不能访问类中的私有属性和方法
# print(daqiu.__money)
# daqiu.__info_print()

xiaoqiu = Tusun()
# # 子类无法继承父类的私有属性和私有方法,这是显而易见的,因为父类的对象都不能访问私有属性,那么子类对象更加没法访问父类的私有属性了
# print(xiaoqiu.__money)  # 无法访问实例属性__money
# xiaoqiu.__info_print()
# # 私有属性和私有方法只能在类里面访问和修改。


print("\n - 9 - ****************************************************************************************************")
class Master(object):
    def __init__(self):
        self.kongfu = '[师傅教的制作煎饼的方法]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作经典葱油饼')


class School(object):
    def __init__(self):
        self.kongfu = '[小乐经典葱油饼配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作经典葱油饼')


class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创经典葱油饼配方]'
        self.__money = 2000000

    # 获取私有属性
    def get_money(self):
        return self.__money

    # 修改私有属性
    def set_money(self):
        self.__money = 5000

    def __info_print(self):
        print(self.kongfu)
        print(self.__money)

    def make_cake(self):
        self.__init__()
        print(f'运用{self.kongfu}制作经典葱油饼')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)


# 徒孙类
class Tusun(Prentice):
    pass


# 实例定义 - 在类名后+()
daqiu = Prentice()
daqiu.__moneyq = 222
print(daqiu.__moneyq)
print(daqiu.__class__)
print("seee this one - ", Prentice.__bases__)
print(daqiu.__dict__)


print(daqiu.get_money())
daqiu.set_money()
print(daqiu.get_money())
print("see what's this - ", daqiu._Prentice__money) # 其实还是可以访问 __money ,可以通过 daqiu._Prentice__money 访问到 __money 属性,为什么能这么访问这里不多讲,他与python的机制有关。


xiaoqiu = Tusun()
# 调用get_money函数获取私有属性money的值
print(xiaoqiu.get_money())
# 调用set_money函数修改私有属性money的值
xiaoqiu.set_money()
print(xiaoqiu.get_money())
# 在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值。

4. 一点总结 -

对象属性和雷属性的几点理解 - 对象属性和类属性

  1. 使用对象创建的属性 称之为对象属性 只有当前对象里才存在
  2. 如果使用对象属性创建了一个和类里面同名的属性 那么调用的时候 会优先查找对象里面的属性
  3. 使用类里面的方法的参数 self 创建的属性 也为对象属性
  4. 当使用对象.属性名来改类里面的属性的时候 其实是在对象里面创建了一个同名的属性
  5. 当将对象里面同名的属性删除掉以后 还是会调用类的属性
  6. 不能再对象里 删除 类里面的属性 只有使用的权利
  7. 使用类操作过的属性 所有对象在调用类属性的时候 都是修改后的属性

类的私有属性和私有方法

私有属性 和 私有方法
(1) 类的私有属性:以__ 作为开头 不能再类的外部进行使用和访问 在类的里面使用 self.__属性名
私有属性的访问
在类的外部: 对象._类名__属性名 查找
在类的内部: 方法里面的变量 self._属性名 调用
注意: 在类的内部只要使用self._属性名 那么就会去找私有属性_类名__属性名

(2) 类的私有方法
​ 以_
作为开头 不能再类的外部进行使用和访问 在类的里面使用 self.__方法名
在公有方法里面 通过self去调用

类的常用属性

__doc__ 类的说明
__name__返回类名
__base__ 返回一个父类
__bases__ 返回多个父类
__dict__ 返回对象或者类的信息

Author: Alan_Yuan
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Alan_Yuan !
  TOC