对象


对象:

对象是内存中专门用来存储数据的一块区域。
对象由三部分组成:

  1. 对象的标识(id )
  2. 对象的类型(type)
  3. 对象的值(value)

类(class)

类是一个用来创建对象的对象。
类是一个type类型的对象,定义类实际上就是定义了一个type类型的对象。

定义类:

在类的代码块中,可以定义变量和函数。类中定义的函数我们称为方法,这些方法可以通过该类的所有实例来访问

  • 调用方法:对象.方法名()

方法调用和函数调用的区别:

  • 函数调用时传几个实参就会有几个实参
  • 方法调用默认传递一个参数,所以方法中至少要定义一个形参

注意:方法调用时,第一个参数由解析器自动传递,所以定义方法时,至少定义一个形参。

一般情况下,属性保存到实例对象中,而方法需要保存到类对象中

方法每次被调用时,解析器都会自动传递一个实参,第一个参数就是调用方法的对象本身。一般我们都会将这个参数命名为 self

# 语法
class 类名([父类]):
	代码块

# 定义一个最简单的类
class Myclass():
	pass

使用类创建对象:

class MyClass():
  pass

myclass = MyClass()
myclass1 = MyClass()
myclass2 = MyClass()

# myclass,myclass1,myclass2都是MyClass的实例,都是一类对象
print(myclass,type(myclass))
print(myclass1,type(myclass1))
print(myclass2,type(myclass2))

# isinstance()用来检查一个对象是否是一个类的实例
result = isinstance(myclass,MyClass)
print(result)

对象的初始化

  • 在类中可以定义一些特殊方法,以__开头,以__结尾。
  • 特殊方法会在特殊时刻自动调用,我们不要尝试去调用

创建一个Person类

class Person() :

    def __init__(self,name,age,gender) :
        self.name = name
        self.age = age
        self.gender = gender

    def say_hello() :
        print('我的名字叫%s'%self.name)

# 创建Person类的实例
person = Person('小明',18,'男')

print(person)
print(person.name,person.age,person.gender)

创建对象的流程:

  1. 创建一个变量
  2. 在内存中创建一个新对象
  3. init(self) 方法执行
  4. 将对象的 id 赋值给变量
  • init 可以用来向新创建的对象中初始化属性。调用类创建对象时,类后边的所有参数都会依次传递到init() 中

面向对象三大特征

封装

  • 确保对象中的数据安全

继承

  • 保证了对象的可扩展性

多态

  • 保证了程序的灵活性

封装

封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法。
封装是面向对象的三大特性之一。

使用封装增加了类的定义的复杂程度,但是确保了数据的安全。

隐藏对象中的属性(一)

  • 隐藏对象中的属性可以将属性名改为一个外部不知道的名字
  • 通过getter和setter方法来调用和修改属性的值
class Person() :

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

    def set_name(self,name) :
        self.hidden_name = name

    def get_name(self) :
        return self.hidden_name

person = Person('小明')
print(person.get_name())

person.set_name('李明')
print(person.get_name())

隐藏对象的属性(二)

  • 隐藏属性可以使对象的属性名使用双下划线 __ 开头,例如 __xxx
  • 双下划线开头的属性使对象的隐藏属性,隐藏属性只能在类的内部访问。
  • 隐藏属性的原理是python自动将属性名修改为 _类名__属性名 这种形式

使用__开头的属性实际上依然可以在外部访问,所以这种方式一般不使用。

class Person() :

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

    def set_name(self,name) :
        self.__name = name

    def get_name(self) :
        return self.__name

person = Person('小明')
print(person._Person__name)

person._Person__name = '李明'
print(person.get_name())
#小明
#李明

隐藏对象的属性(三)(推荐使用)

一般我们会将私有属性(不希望被外部访问的属性)以 _ 开头。

  • property装饰器用来将一个get方法转换为对象的属性。添加property装饰器以后,我们可以像调用属性一样使用get方法。
  • 使用property装饰的方法,方法名必须和属性名相同
  • 属性名.setter 装饰器同理,用于setter方法
class Person():
    def __init__(self,name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self,name):
        self._name = name

person = Person('小明')
print(person.name)

person.name = '李明'
print(person.name)
# 小明
# 李明

继承

  • 继承是面向对象的三大特征之一。
  • 通过继承我们可以使一个类获取到其他类中的属性和方法。
  • 在定义类时可以在类名后的括号中指定当前类的父类(超类、基类、super),子类(衍生类)可以直接继承父类中所有的属性和方法。

创建类时如果省略了父类,则默认父类为object。object时所有类的父类,所有类都继承自object。

class Person:
  def sleep(self):
    print('睡觉')
  
  def eat(self):
    print('吃饭')

class Man(Person):
  def work(self):
    print('赚钱养家')
man = Man()
man.sleep()
man.eat()
man.work()

issubclass()

issubclass() :检查一个类是否是另一个类的子类

isinstance()

isinstance() :检查一个对象是否是一个类的实例

class Person:
  def sleep(self):
    print('睡觉')
  
  def eat(self):
    print('吃饭')

class Man(Person):
  def work(self):
    print('赚钱养家')

man = Man()
# 检查Man() 是否是Person()的子类
print(issubclass(Man,Person))

# 检查man是否是Man()的实例
print(isinstance(man,Man))

supper()

  • 父类中的所有的方法都会被子类继承,包括特殊方法,所以也就可以重写特殊方法。
  • 我们希望可以直接调用父类的 init 来初始化父类中定义的属性

supper() 可以用来获取当前类的父类,并且通过 super() 返回对象调用方法时,不需要传递self

class Person:

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

  def sleep(self):
    print('睡觉')
  
  def eat(self):
    print('吃饭')

  @property
  def name(self):
    return self._name

  @name.setter
  def name(self,name):
    self._name = name 

# 父类中的所有方法都会被子类继承,包括特殊方法,当然也可以重写特殊方法
class Man(Person):
  def __init__(self,name,age):
    #super()可以用来获取当前类的父类
    #通过supper()返回对象调用父类方法时,不需要传递self
    super().__init__(name)
    self._age = age

  def work(self):
    print('赚钱养家')

  @property
  def age(self):
    return self._age

  @age.setter
  def age(self,age):
    self._age = age

man = Man('张三',22)
print(man.name) # 张三
print(man.age) #22

多重继承

  1. 在Python中支持多重继承,即一个类可以同时继承多个父类
  2. 在类名后面的()中添加多个类来实现多重继承
  3. 多重继承会使子类同时拥有多个父类,并且会获取到所有父类中的方法
  4. 在开发中没有特殊的情况,应该尽量避免使用多重继承,因为多重继承会让我们的代码过于复杂
  5. 如果多个父类中有同名的方法,则会现在第一个父类中寻找,然后找第二个,然后找第三个…以此类推
  6. 前边父类的方法会覆盖后边父类的方法。
class A(object):
    def test(self):
        print('aaa')

class B(object):
    def test(self):
        print('bbb')

class C(A,B):
    pass

c = C()
c.test() # aaa

重写(覆盖)

重写:如果在子类中有和父类同名的方法,则通过子类实例去调用方法时,会调用子类的方法而不是父类的方法

  • 当我们调用一个对象的方法时会优先去当前对象的类中寻找,如果有则调用;
  • 如果没有找到,就会去当前类的父类中寻找,如果有则调用;
  • 如果父类中没有找到,则去父类的父类中寻找,直到找到object类也没有找到就会报错。

多态

多态:一个对象可以以不同的形态去呈现
多态是面向对象的三大特征之一。

具体点击该链接查看尚硅谷课程:多态

类中的属性和方法

类属性

  • 直接在类中定义的属性是类属性。
  • 类属性可以通过类或类的实例访问到
  • 类属性只能通过类对象来修改,无法通过实例对象修改

实例属性

  • 通过实例对象添加的属性属于实例属性
  • 实例属性只能通过实例对象来访问和修改,类对象无法访问修改

类方法

  • 在类内部使用 @classmethod 来修饰的方法属于类方法
  • 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象
  • 类方法和实例方法的区别:实例方法的第一个参数是self,而类方法的第一个参数是cls
  • 类方法可以通过类调用,也可以通过实例调用,没有区别

实例方法

  • 在类中定义,以self为第一个参数的方法都是实例方法
  • 实例方法在调用时,python会将调用对象作为self传入
  • 实例对象可以通过实例和类去调用
  • 当通过实例调用时,会自动将当前调用对象作为self传入
  • 当通过类调用时,不会自动传递self,此时我们必须手动传递self

静态方法

  • 在类中使用 @staticmethod 来修饰的方法属于静态方法
  • 静态方法不需要指定任何默认参数,静态方法可以通过类和实例调用
  • 静态方法一般都是一些工具方法,和当前类无关,相当于一个保存到当前类中的函数
class A(object):
    #类属性,直接在类中定义
    num = 0

    def __init__(self):
        #实例属性,通过实例对象添加的属性
        self._name = '悟空'

    #实例方法,在类中定义,以self为第一个参数
    def test(self):
        print('test方法,也是一个实例方法')

    #类方法,在类内部使用@classmethod修饰
    @classmethod
    def test1(cls):
        print('test1方法,也是一个类方法',cls)
        print(cls.num)

    #静态方法
    @staticmethod
    def test2():
        print('test2方法,也是一个静态方法')


a = A()
#实例属性,通过实例对象添加的属性
a.res = 2
print(a.res)

模块

  • 模块化是指将一个完整的程序分解为一个个小的模块,通过模块组合来搭建出一个完整的程序
  • 模块化方便开发,方便维护,代码可以复用
  • python中一个py文件就是一个模块(命名要符合标识符的规范)

在一个模块中引入外部模块

  • 可以引入同一个模块多次,但是模块的实例只会创建一个
  • import 可以在程序的任意位置调用,一般都写在第一行
# 引入模块的语法
import 模块名
import 模块名 as 模块别名

模块内部有一个__name__属性,通过这个属性可以获取到当前模块的名字。主模块是直接通过python执行的模块,__name__属性值为__main__的模块是主模块,一个程序只有一个主模块。

也可以只引入模块中的部分内容

# 语法
from 模块名 import 变量1,变量2,...
# 引入模块所有内容
from 模块名 import *
# 也可以为引入的变量使用别名
from 变量名 import 变量 as 别名

包(package)

  • 包也是一个模块。普通的包是一个py文件,包是一个文件夹。
  • 包中必须要有一个__init__文件,这个文件可以包含包中的主要内容。
  • __pycache__是模块的缓存文件。
  • py代码在执行前,需要被解析器先转换为机器码,然后再执行
  • 所以在使用模块(包)时,也需要将模块的代码先转换为机器码然后再交由计算机执行
  • 为了提高程序运行的性能,python会在编译过一次以后,将代码保存到一个缓存文件中。这样在下次加载这个模块(包)时,就可以不再重新编译而是直接加载缓存中编译报的代码即可

Python的标准库

sys模块里面提供了一些变量和函数,使我们可以获取到Python解析器的信息,或者通过函数来操作Python解析器

  • sys.argv :获取执行代码时,命令行中所包含的参数
  • sys.modules :获取当前程序中引入的所有模块。modules是一个字典,字典的key是模块的名字,字典的value是模块对象。
  • sys.path :一个列表,列表中保存模块的搜索路径
  • sys.platform :表示当前Python运行的平台
  • sys.exit() :函数用来退出程序

pprint模块提供了一个 pprint() 方法,该方法可以用来对打印的数据做简单的格式化

os 模块让我们可以对操作系统进行访问

  • os.environ :通过这个属性可以获取到系统的环境变量
  • os.system() :可以用来执行操作系统的命令
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值