内容简介:Python 是一门完全面向对象的语言。在 Python 中,一切都是对象。从我们开始使用 Python 时,我们就已经使用了 Python 中的对象和类。Python 程序中的每一个元素都是类的一个实例,如数字、字符串、列表、字典这些元素,都是 Python 内置类对应的一个对象,甚至于使用Python 使用
Python 是一门完全面向对象的语言。在 Python 中,一切都是对象。从我们开始使用 Python 时,我们就已经使用了 Python 中的对象和类。
Python 程序中的每一个元素都是类的一个实例,如数字、字符串、列表、字典这些元素,都是 Python 内置类对应的一个对象,甚至于使用 def
关键字定义的一个函数都对应一个 function
类。
面向对象基础
Python 使用 class
关键字声明一个类。
一个典型的 Python 类主要包含以下成员:
- 构造函数 (constructor)
- 实例属性 (Instance Attributes)
- 类属性 (Class Attributes)
- 方法 (Class Attributes)
一个类也可以没有任何成员,如下面的 Car
类就没有任何成员:
class Car: '''This is an empty Car Class''' pass
下面的类则包含了实例属性、类属性、构造函数、方法等成员:
class Car: brand = 'BenChi' def __init__(self): self.price = 10000 self.chair = 7 def run(self): print('Run 100km Per Hour....')
构造函数
在 Python 中,构造函数是实例化一个类对象的时自动被调用的函数,类似于 Java 或 C# 中的构造函数。构造函数必须使用一个特定的名称 __init__
,并且必须有一个固定的参数 self
。
Python 类中 几乎
每一个方法都要将 self 作为第一个参数,self 是调用该方法的对象的引用。其实,第一个参数的名字是任意的,并不一定要叫 self, self 只是一种约定。
注意,注意,注意: __init__
方法并不是 Python 类构造函数,关于 Python 类的构造函数其实有很大争议,这里主要是为了介绍面向对象的概念。
下面的例子定义了一个构造函数:
class Car: def __init__(self): print('Call Constructor......') car1 = Car() car2 = Car()
Python 中构造函数( init )的作用定义了类实例的属性,并对实例属性进行复制。
实例属性
实例属性是与类实例绑定的属性,其定义在构造函数( init )中。
下面的例子定义了两个实例属性:
class Car: def __init__(self): self.price = 100 self.chair = 7
类属性
类属性不同于实例属性,类属性的值被所有实例对象共享。类属性在类级别定义而不是定义在 __init__
方法中。类属性的访问也不同于实例属性,类属性的访问是通过类名, 也可以通过实例访问。
下面例子定义了一个类属性:
class Car: brand = "benchi" print(Car.brand)
通过类名修改类属性
通过类名修改类属性,那么该类所有的实例对象对应的类属性都会被修改, 如下:
class Car: brand = "benchi" car1 = Car() car2 = Car() print('Before Change.............') print(f'car1 brand is: {car1.brand}') print(f'car2 brand is: {car2.brand}') print('Change Class Attribute By [Class Name]') Car.brand = 'Audi' print('After Change.............') print(f'car1 brand is: {car1.brand}') print(f'car2 brand is: {car2.brand}') 输出: Before Change............. car1 brand is: benchi car2 brand is: benchi Change Class Attribute By [Class Name] After Change............. car1 brand is: Audi car2 brand is: Audi
通过实例对象修改类属性
通过实例对象修改类属性,并不会影响其他对象类属性的值,他仅仅影响该实例对象自己类属性的值,如下:
class Car: brand = "benchi" car1 = Car() car2 = Car() print('Before Change.............') print(f'car1 brand is: {car1.brand}') print(f'car2 brand is: {car2.brand}') print('Change Class Attribute By [Object]') car1.brand = 'Audi' car2.brand = 'KaYan' print('After Change.............') print(f'car1 brand is: {car1.brand}') print(f'car2 brand is: {car2.brand}') print(f'Car brand is: {Car.brand}') 输出: Before Change............. car1 brand is: benchi car2 brand is: benchi Change Class Attribute By [Object] After Change............. car1 brand is: Audi car2 brand is: KaYan Car brand is: benchi
类方法
在一个类中,可以定义尽可能多的类方法,一般情况下,类方法的第一个参数都是 self
。
下面的类就定义了一个类方法:
class Car: brand = "benchi" def run(self): print('Run......')
面向对象之封装
面向对象语言,如Java、C++等,使用 public
、 protected
、 private
等关键字来控制对类资源的访问。
-
类的
private
成员仅能在类内部进行访问,其他任何地方都不能访问,包括其子类。 -
类的
protected
成员可以在类内部和其子类中访问。 -
类的
public
成员可以在任何地方进行访问。
Python没有使用关键字机制来限制对类成员方法和类成员属性的访问,Python规定了一种约定,在类方法或者类成员前加 _
(下划线)或者 __
(双下划线)来模拟 private
或者 public
访问修饰期的功能。
public成员
Python中的所有成员默认都是 public
属性,可以在任何地方访问。
如下代码:
class Car: def __init__(self, brand, price): self.brand = brand self.price = price def run(self): print('Run......') brand = 'Audi' price = 10000 car = Car(brand, price) # 访问类属性 print(car.brand) print(car.price) # 访问类方法 car.run() 输出结果: Audi 10000 Run......
protected成员
Python约定,如果类成员前加了单个下划线 _
, 则类成员为protected成员。
class Car: def __init__(self, brand, price): self._brand = brand self._price = price def _run(self): print('Run......') brand = 'Audi' price = 10000 car = Car(brand, price) # 访问protected属性 print(car._brand) print(car._price) # 修改protected属性 car._price = 20000 print(car._price) # 访问类方法 car._run() 输出结果: Audi 10000 20000 Run......
使用单下划线的方式将属性声明为 protected
, 并不能真正起到作用,它仅仅是一种约定。
private成员
Python约定,如果类成员前加了双下划线 __
, 则类成员为private成员。
如下代码:
class Car: def __init__(self, brand, price): self._brand = brand self._price = price def __run(self): print('Run......') # 访问类方法 car._run() # 程序报错,'Car' object has no attribute '_run'
面向对象之继承
在面向对象编程中,继承是达到代码重用目的的一种方式。在继承中,子类可以使用其父类的一部分代码。
继承的基本使用
下面先创建一个父类, 代码如下:
class Fish: def __init__(self, first_name, last_name="Fish", skeleton="bone", eyelids=False): self.first_name = first_name self.last_name = last_name self.skeleton = skeleton self.eyelids = eyelids def swim(self): print("The fish is swimming.") def swim_backwards(self): print("The fish can swim backwards.")
接下来,创建一个没有任何方法和属性的子类,代码如下:
class Trout(Fish): pass
Python类继承的语法是在定义类的时候,传入父类的名字作为参数
由于 Trout
类继承了 Fish
类, Trout
类就是 Fish
类的子类, Trout
类的对象就可以调用其父类的所有方法,代码如下:
terry = Trout("Terry") print(terry.first_name + " " + terry.last_name) print(terry.skeleton) print(terry.eyelids) terry.swim() terry.swim_backwards() 输出: Terry Fish bone False The fish is swimming. The fish can swim backwards.
接下来,再创建另一个子类,该子类有自己的方法:
class Clownfish(Fish): def live_with_anemone(self): print("The clownfish is coexisting with sea anemone.")
创建 Clownfish
的一个对象,并调用其方法:
class Clownfish(Fish): def live_with_anemone(self): print("The clownfish is coexisting with sea anemone.") casey = Clownfish("Casey") print(casey.first_name + " " + casey.last_name) casey.swim() casey.live_with_anemone() 输出: Casey Fish The fish is swimming. The clownfish is coexisting with sea anemone.
从输出结果可以看出, Clownfish
的对象 casey
可以调用其父类的 swim()
方法和 __init__()
方法,同时可以调用它自身的 live_with_anemone()
方法。
覆盖父类方法
有时候,子类继承了父类的全部方法和属性,但是只想使用其中的一部分方法和属性,当子类定义了和父类一样的方法时,就会覆盖(override)父类的方法。
有一点需要注意的是,尽管子类覆盖了父类的方法,但是并没有产生多余的代码。
下面定义一个覆盖父类 __init__()
方法和 swim_backwards()
方法的类:
class Shark(Fish): def __init__(self, first_name, last_name="Shark", skeleton="cartilage", eyelids=True): self.first_name = first_name self.last_name = last_name self.skeleton = skeleton self.eyelids = eyelids def swim_backwards(self): print("The shark cannot swim backwards, but can sink backwards.") sammy = Shark("Sammy") print(sammy.first_name + " " + sammy.last_name) sammy.swim() sammy.swim_backwards() print(sammy.eyelids) print(sammy.skeleton) 结果: Sammy Shark The fish is swimming. The shark cannot swim backwards, but can sink backwards. True cartilage
从输出结果可以看出,子类成功覆盖了父类的方法。
super()函数
如果子类覆盖了父类的方法,同时又想使用父类的方法,可以使用 super()
函数。
super()
函数经常在 __init__()
方法中被使用。
修改一下上文所提到的 Trout
类,代码如下:
class Trout(Fish): def __init__(self, water = "freshwater"): self.water = water super().__init__(self) terry = Trout() terry.first_name = "Terry" print(terry.first_name + " " + terry.last_name) print(terry.eyelids) print(terry.water) terry.swim() 输出: Terry Fish False freshwater The fish is swimming.
从输出结果可以看出,使用 super()
函数成功调用了父类被子类覆盖的方法。
多重继承
多重继承即一个类可以继承多个类。
多重继承基本语法如下:
class Coral: def community(self): print("Coral lives in a community.") class Anemone: def protect_clownfish(self): print("The anemone is protecting the clownfish.") class CoralReef(Coral, Anemone): pass
总结
本篇文章总结了Python面向对象的基本概念及基本使用方法,弥补自己在Python方面面向对象方法的不足。
参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 面向Python,面向对象(基础)
- 面向Python,面向对象(基础3)
- <<深入PHP面向对象、模式与实践>>读书笔记:面向对象设计和过程式编程
- 《JavaScript面向对象精要》之六:对象模式
- 《JavaScript面向对象精要》之三:理解对象
- 面向对象的程序设计之理解对象
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
郎咸平说:新经济颠覆了什么
郎咸平 / 东方出版社 / 2016-8 / 39.00元
正所谓“上帝欲其灭亡,必先令其疯狂”,在当下中国,“互联网+资本催化”的新经济引擎高速运转,大有碾压一切、颠覆一切之势。在新经济狂热之下,每个人都在全力以赴寻找“下一个风口”,幻想成为下一只飞起来的猪。 对此,一向以“危机论”著称的郎咸平教授再次发出盛世危言:新经济光环背后,危机已悄然而至!中国式O2O还能烧多久?P2P监管黑洞有多大?互联网造车为什么不靠谱?共享经济为什么徒有虚名?BAT为......一起来看看 《郎咸平说:新经济颠覆了什么》 这本书的介绍吧!