Python面向对象进阶学习

在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息。为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程进行更为深入的了解。

@property装饰器

之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效。我们之前的建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作。如果要做到这点,就可以考虑使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便,代码如下所示。

class Person(object):

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

 # 访问器 - getter方法
 @property
 def name(self):
  return self._name

 # 访问器 - getter方法
 @property
 def age(self):
  return self._age

 # 修改器 - setter方法
 @age.setter
 def age(self, age):
  self._age = age

 def play(self):
  if self._age <= 16:
   print('%s正在玩飞行棋.' % self._name)
  else:
   print('%s正在玩斗地主.' % self._name)

def main():
 person = Person('王大锤', 12)
 person.play()
 person.age = 22
 person.play()
 # person.name = '白元芳' # AttributeError: can't set attribute

if __name__ == '__main__':
 main()

__slots__魔法

我们讲到这里,不知道大家是否已经意识到,Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

class Person(object):

 # 限定Person对象只能绑定_name, _age和_gender属性
 __slots__ = ('_name', '_age', '_gender')

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

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

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

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

 def play(self):
  if self._age <= 16:
   print('%s正在玩飞行棋.' % self._name)
  else:
   print('%s正在玩斗地主.' % self._name)

def main():
 person = Person('王大锤', 22)
 person.play()
 person._gender = '男'
 # AttributeError: 'Person' object has no attribute '_is_gay'
 # person._is_gay = True

静态方法和类方法

之前,我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息。实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。我们可以使用静态方法来解决这类问题,代码如下所示。

from math import sqrt

class Triangle(object):

 def __init__(self, a, b, c):
  self._a = a
  self._b = b
  self._c = c

 @staticmethod
 def is_valid(a, b, c):
  return a + b > c and b + c > a and a + c > b

 def perimeter(self):
  return self._a + self._b + self._c

 def area(self):
  half = self.perimeter() / 2
  return sqrt(half * (half - self._a) *
     (half - self._b) * (half - self._c))

def main():
 a, b, c = 3, 4, 5
 # 静态方法和类方法都是通过给类发消息来调用的
 if Triangle.is_valid(a, b, c):
  t = Triangle(a, b, c)
  print(t.perimeter())
  # 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
  # print(Triangle.perimeter(t))
  print(t.area())
  # print(Triangle.area(t))
 else:
  print('无法构成三角形.')

if __name__ == '__main__':
 main()

和静态方法比较类似,Python还可以在类中定义类方法,类方法的第一个参数约定名为cls,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象,代码如下所示。

from time import time, localtime, sleep

class Clock(object):
 """数字时钟"""

 def __init__(self, hour=0, minute=0, second=0):
  self._hour = hour
  self._minute = minute
  self._second = second

 @classmethod
 def now(cls):
  ctime = localtime(time())
  return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)

 def run(self):
  """走字"""
  self._second += 1
  if self._second == 60:
   self._second = 0
   self._minute += 1
   if self._minute == 60:
    self._minute = 0
    self._hour += 1
    if self._hour == 24:
     self._hour = 0

 def show(self):
  """显示时间"""
  return '%02d:%02d:%02d' % \
    (self._hour, self._minute, self._second)

def main():
 # 通过类方法创建对象并获取系统时间
 clock = Clock.now()
 while True:
  print(clock.show())
  sleep(1)
  clock.run()

if __name__ == '__main__':
 main()

类之间的关系

简单的说,类和类之间的关系有三种:is-a、has-a和use-a关系。

is-a关系也叫继承或泛化,比如学生和人的关系、手机和电子产品的关系都属于继承关系。
has-a关系通常称之为关联,比如部门和员工的关系,汽车和引擎的关系都属于关联关系;关联关系如果是整体和部分的关联,那么我们称之为聚合关系;如果整体进一步负责了部分的生命周期(整体和部分是不可分割的,同时同在也同时消亡),那么这种就是最强的关联关系,我们称之为合成关系。

use-a关系通常称之为依赖,比如司机有一个驾驶的行为(方法),其中(的参数)使用到了汽车,那么司机和汽车的关系就是依赖关系。

我们可以使用一种叫做UML(统一建模语言)的东西来进行面向对象建模,其中一项重要的工作就是把类和类之间的关系用标准化的图形符号描述出来。关于UML我们在这里不做详细的介绍,有兴趣的读者可以自行阅读《UML面向对象设计基础》一书。

利用类之间的这些关系,我们可以在已有类的基础上来完成某些操作,也可以在已有类的基础上创建新的类,这些都是实现代码复用的重要手段。复用现有的代码不仅可以减少开发的工作量,也有利于代码的管理和维护,这是我们在日常工作中都会使用到的技术手段。

继承和多态

刚才我们提到了,可以在已有类的基础上创建新类,这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力,在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,对应的原则称之为里氏替换原则。下面我们先看一个继承的例子。

class Person(object):
 """人"""

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

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

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

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

 def play(self):
  print('%s正在愉快的玩耍.' % self._name)

 def watch_av(self):
  if self._age >= 18:
   print('%s正在观看爱情动作片.' % self._name)
  else:
   print('%s只能观看《熊出没》.' % self._name)

class Student(Person):
 """学生"""

 def __init__(self, name, age, grade):
  super().__init__(name, age)
  self._grade = grade

 @property
 def grade(self):
  return self._grade

 @grade.setter
 def grade(self, grade):
  self._grade = grade

 def study(self, course):
  print('%s的%s正在学习%s.' % (self._grade, self._name, course))

class Teacher(Person):
 """老师"""

 def __init__(self, name, age, title):
  super().__init__(name, age)
  self._title = title

 @property
 def title(self):
  return self._title

 @title.setter
 def title(self, title):
  self._title = title

 def teach(self, course):
  print('%s%s正在讲%s.' % (self._name, self._title, course))

def main():
 stu = Student('王大锤', 15, '初三')
 stu.study('数学')
 stu.watch_av()
 t = Teacher('骆昊', 38, '老叫兽')
 t.teach('Python程序设计')
 t.watch_av()

if __name__ == '__main__':
 main()

子类在继承了父类的方法后,可以对父类已有的方法给出新的实现版本,这个动作称之为方法重写(override)。通过方法重写我们可以让父类的同一个行为在子类中拥有不同的实现版本,当我们调用这个经过子类重写的方法时,不同的子类对象会表现出不同的行为,这个就是多态(poly-morphism)。

from abc import ABCMeta, abstractmethod

class Pet(object, metaclass=ABCMeta):
 """宠物"""

 def __init__(self, nickname):
  self._nickname = nickname

 @abstractmethod
 def make_voice(self):
  """发出声音"""
  pass

class Dog(Pet):
 """狗"""

 def make_voice(self):
  print('%s: 汪汪汪...' % self._nickname)

class Cat(Pet):
 """猫"""

 def make_voice(self):
  print('%s: 喵...喵...' % self._nickname)

def main():
 pets = [Dog('旺财'), Cat('凯蒂'), Dog('大黄')]
 for pet in pets:
  pet.make_voice()

if __name__ == '__main__':
 main()

在上面的代码中,我们将Pet类处理成了一个抽象类,所谓抽象类就是不能够创建对象的类,这种类的存在就是专门为了让其他类去继承它。Python从语法层面并没有像Java或C#那样提供对抽象类的支持,但是我们可以通过abc模块的ABCMeta元类和abstractmethod包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化(创建对象)。上面的代码中,Dog和Cat两个子类分别对Pet类中的make_voice抽象方法进行了重写并给出了不同的实现版本,当我们在main函数中调用该方法时,这个方法就表现出了多态行为(同样的方法做了不同的事情)。

综合案例

案例1:奥特曼打小怪兽

from abc import ABCMeta, abstractmethod
from random import randint, randrange

class Fighter(object, metaclass=ABCMeta):
 """战斗者"""

 # 通过__slots__魔法限定对象可以绑定的成员变量
 __slots__ = ('_name', '_hp')

 def __init__(self, name, hp):
  """初始化方法

  :param name: 名字
  :param hp: 生命值
  """
  self._name = name
  self._hp = hp

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

 @property
 def hp(self):
  return self._hp

 @hp.setter
 def hp(self, hp):
  self._hp = hp if hp >= 0 else 0

 @property
 def alive(self):
  return self._hp > 0

 @abstractmethod
 def attack(self, other):
  """攻击

  :param other: 被攻击的对象
  """
  pass

class Ultraman(Fighter):
 """奥特曼"""

 __slots__ = ('_name', '_hp', '_mp')

 def __init__(self, name, hp, mp):
  """初始化方法

  :param name: 名字
  :param hp: 生命值
  :param mp: 魔法值
  """
  super().__init__(name, hp)
  self._mp = mp

 def attack(self, other):
  other.hp -= randint(15, 25)

 def huge_attack(self, other):
  """究极必杀技(打掉对方至少50点或四分之三的血)

  :param other: 被攻击的对象

  :return: 使用成功返回True否则返回False
  """
  if self._mp >= 50:
   self._mp -= 50
   injury = other.hp * 3 // 4
   injury = injury if injury >= 50 else 50
   other.hp -= injury
   return True
  else:
   self.attack(other)
   return False

 def magic_attack(self, others):
  """魔法攻击

  :param others: 被攻击的群体

  :return: 使用魔法成功返回True否则返回False
  """
  if self._mp >= 20:
   self._mp -= 20
   for temp in others:
    if temp.alive:
     temp.hp -= randint(10, 15)
   return True
  else:
   return False

 def resume(self):
  """恢复魔法值"""
  incr_point = randint(1, 10)
  self._mp += incr_point
  return incr_point

 def __str__(self):
  return '~~~%s奥特曼~~~\n' % self._name + \
   '生命值: %d\n' % self._hp + \
   '魔法值: %d\n' % self._mp

class Monster(Fighter):
 """小怪兽"""

 __slots__ = ('_name', '_hp')

 def attack(self, other):
  other.hp -= randint(10, 20)

 def __str__(self):
  return '~~~%s小怪兽~~~\n' % self._name + \
   '生命值: %d\n' % self._hp

def is_any_alive(monsters):
 """判断有没有小怪兽是活着的"""
 for monster in monsters:
  if monster.alive > 0:
   return True
 return False

def select_alive_one(monsters):
 """选中一只活着的小怪兽"""
 monsters_len = len(monsters)
 while True:
  index = randrange(monsters_len)
  monster = monsters[index]
  if monster.alive > 0:
   return monster

def display_info(ultraman, monsters):
 """显示奥特曼和小怪兽的信息"""
 print(ultraman)
 for monster in monsters:
  print(monster, end='')

def main():
 u = Ultraman('骆昊', 1000, 120)
 m1 = Monster('狄仁杰', 250)
 m2 = Monster('白元芳', 500)
 m3 = Monster('王大锤', 750)
 ms = [m1, m2, m3]
 fight_round = 1
 while u.alive and is_any_alive(ms):
  print('========第%02d回合========' % fight_round)
  m = select_alive_one(ms) # 选中一只小怪兽
  skill = randint(1, 10) # 通过随机数选择使用哪种技能
  if skill <= 6: # 60%的概率使用普通攻击
   print('%s使用普通攻击打了%s.' % (u.name, m.name))
   u.attack(m)
   print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
  elif skill <= 9: # 30%的概率使用魔法攻击(可能因魔法值不足而失败)
   if u.magic_attack(ms):
    print('%s使用了魔法攻击.' % u.name)
   else:
    print('%s使用魔法失败.' % u.name)
  else: # 10%的概率使用究极必杀技(如果魔法值不足则使用普通攻击)
   if u.huge_attack(m):
    print('%s使用究极必杀技虐了%s.' % (u.name, m.name))
   else:
    print('%s使用普通攻击打了%s.' % (u.name, m.name))
    print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
  if m.alive > 0: # 如果选中的小怪兽没有死就回击奥特曼
   print('%s回击了%s.' % (m.name, u.name))
   m.attack(u)
  display_info(u, ms) # 每个回合结束后显示奥特曼和小怪兽的信息
  fight_round += 1
 print('\n========战斗结束!========\n')
 if u.alive > 0:
  print('%s奥特曼胜利!' % u.name)
 else:
  print('小怪兽胜利!')

if __name__ == '__main__':
 main()

案例2:扑克游戏

import random

class Card(object):
 """一张牌"""

 def __init__(self, suite, face):
  self._suite = suite
  self._face = face

 @property
 def face(self):
  return self._face

 @property
 def suite(self):
  return self._suite

 def __str__(self):
  if self._face == 1:
   face_str = 'A'
  elif self._face == 11:
   face_str = 'J'
  elif self._face == 12:
   face_str = 'Q'
  elif self._face == 13:
   face_str = 'K'
  else:
   face_str = str(self._face)
  return '%s%s' % (self._suite, face_str)

 def __repr__(self):
  return self.__str__()

class Poker(object):
 """一副牌"""

 def __init__(self):
  self._cards = [Card(suite, face)
      for suite in '♠♥♣♦'
      for face in range(1, 14)]
  self._current = 0

 @property
 def cards(self):
  return self._cards

 def shuffle(self):
  """洗牌(随机乱序)"""
  self._current = 0
  random.shuffle(self._cards)

 @property
 def next(self):
  """发牌"""
  card = self._cards[self._current]
  self._current += 1
  return card

 @property
 def has_next(self):
  """还有没有牌"""
  return self._current < len(self._cards)

class Player(object):
 """玩家"""

 def __init__(self, name):
  self._name = name
  self._cards_on_hand = []

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

 @property
 def cards_on_hand(self):
  return self._cards_on_hand

 def get(self, card):
  """摸牌"""
  self._cards_on_hand.append(card)

 def arrange(self, card_key):
  """玩家整理手上的牌"""
  self._cards_on_hand.sort(key=card_key)

# 排序规则-先根据花色再根据点数排序
def get_key(card):
 return (card.suite, card.face)

def main():
 p = Poker()
 p.shuffle()
 players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]
 for _ in range(13):
  for player in players:
   player.get(p.next)
 for player in players:
  print(player.name + ':', end=' ')
  player.arrange(get_key)
  print(player.cards_on_hand)

if __name__ == '__main__':
 main()

说明: 大家可以自己尝试在上面代码的基础上写一个简单的扑克游戏,例如21点(Black Jack),游戏的规则可以自己在网上找一找。

案例3:工资结算系统

"""
某公司有三种类型的员工 分别是部门经理、程序员和销售员
需要设计一个工资结算系统 根据提供的员工信息来计算月薪
部门经理的月薪是每月固定15000元
程序员的月薪按本月工作时间计算 每小时150元
销售员的月薪是1200元的底薪加上销售额5%的提成
"""
from abc import ABCMeta, abstractmethod

class Employee(object, metaclass=ABCMeta):
 """员工"""

 def __init__(self, name):
  """
  初始化方法

  :param name: 姓名
  """
  self._name = name

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

 @abstractmethod
 def get_salary(self):
  """
  获得月薪

  :return: 月薪
  """
  pass

class Manager(Employee):
 """部门经理"""

 def get_salary(self):
  return 15000.0

class Programmer(Employee):
 """程序员"""

 def __init__(self, name, working_hour=0):
  super().__init__(name)
  self._working_hour = working_hour

 @property
 def working_hour(self):
  return self._working_hour

 @working_hour.setter
 def working_hour(self, working_hour):
  self._working_hour = working_hour if working_hour > 0 else 0

 def get_salary(self):
  return 150.0 * self._working_hour

class Salesman(Employee):
 """销售员"""

 def __init__(self, name, sales=0):
  super().__init__(name)
  self._sales = sales

 @property
 def sales(self):
  return self._sales

 @sales.setter
 def sales(self, sales):
  self._sales = sales if sales > 0 else 0

 def get_salary(self):
  return 1200.0 + self._sales * 0.05

def main():
 emps = [
  Manager('刘备'), Programmer('诸葛亮'),
  Manager('曹操'), Salesman('荀彧'),
  Salesman('吕布'), Programmer('张辽'),
  Programmer('赵云')
 ]
 for emp in emps:
  if isinstance(emp, Programmer):
   emp.working_hour = int(input('请输入%s本月工作时间: ' % emp.name))
  elif isinstance(emp, Salesman):
   emp.sales = float(input('请输入%s本月销售额: ' % emp.name))
  # 同样是接收get_salary这个消息但是不同的员工表现出了不同的行为(多态)
  print('%s本月工资为: ¥%s元' %
    (emp.name, emp.get_salary()))

if __name__ == '__main__':
 main()
(0)

相关推荐

  • 谈一谈基于python的面向对象编程基础

    活在当下的程序员应该都听过"面向对象编程"一词,也经常有人问能不能用一句话解释下什么是"面向对象编程",我们先来看看比较正式的说法. 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)和泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派.

  • Python3.5面向对象程序设计之类的继承和多态详解

    本文实例讲述了Python3.5面向对象程序设计之类的继承和多态.分享给大家供大家参考,具体如下: 1.继承的定义 继承是指:可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展. (1)通过继承创建的新类称为"子类"或"派生类". (2)被继承的类称为"基类"."父类"或"超类". 继承的过程,就是从一般到特殊的过程.要实现继承,可以通过"继承"(Inherit

  • Python面向对象总结及类与正则表达式详解

    Python3 面向对象 -------------------------------------------------------------------------------- 一丶面向对象技术简介 •类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. •方法:类中定义的函数. •类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外.类变量通常不作为实例变量使用. •数据成员:类变量或者实例变

  • python面向对象实现名片管理系统文件版

    本文实例为大家分享了python实现名片管理系统源代码,供大家参考,具体内容如下 import os def print_menu(): print("*"*50) print(" 名片管理系统") print(" 1.添加一个新名片") print(" 2.删除一个名片信息") print(" 3.修改一个名片信息") print(" 4.查找一个名片信息") print("

  • Python3.5面向对象与继承图文实例详解

    本文实例讲述了Python3.5面向对象与继承.分享给大家供大家参考,具体如下: 1.编程的方式 2.面向对象的基本概念 3.类的基本概念 4.类的定义与调用--简单代码举例 注:建议类名的开头字母用大写,在Python中,类内的函数称作方法,类外的函数还是称作函数. #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:ZhengzhengLiu #类 class Person: i = 10 #属性(变量) def eat(self):

  • python面向对象法实现图书管理系统

    本文实例为大家分享了python实现图书管理系统的具体代码,供大家参考,具体内容如下 需求: 图书管理系统 1.查询图书 2.增加图书 3.借阅图书 4.归还图书 5.退出系统 书:书名,作者,状态,位置 管理系统: 实现如下: class Book(object): def __init__(self, name, author, status, bookindex): self.name = name self.author = author self.status = status sel

  • Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为:top-down languages,程序从上到下 一步步执行,从头到尾的解决问题. 基本设计思路为:程序一开始是解决一个大问题,然后把大问题分解成多个小问题或子过程,这些小问题执行的时候再继续分解, 直到小问题足够简单到可以在一个小范围内解决. 缺点:若程序要进行修改,则修改的部分依赖的各个部分也

  • Python面向对象进阶学习

    在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息.为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程进行更为深入的了解. @property装饰器 之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效.我们之前的建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问

  • Python进阶学习之带你探寻Python类的鼻祖-元类

    Python是一门面向对象的语言,所以Python中数字.字符串.列表.集合.字典.函数.类等都是对象. 利用 type() 来查看Python中的各对象类型 In [11]: # 数字 In [12]: type(10) Out[12]: int In [13]: type(3.1415926) Out[13]: float In [14]: # 字符串 In [15]: type('a') Out[15]: str In [16]: type("abc") Out[16]: str

  • python进阶_浅谈面向对象进阶

    学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class Foo: pass class Son(Foo): pass s = Son() #判断一个对象是不是这个类的对象,传两个参数(对象,类) print(isinstance(s,Son)) print(isinstance(s,Foo)) #type更精准 print(type(s) is Son) print(type(s) is Fo

  • python 进阶学习之python装饰器小结

    装饰器总结 什么是装饰器?处理函数的函数,加一个功能,但是不影响原来函数的内部结构生活中的例子:给手机加一个外壳,外壳保护了手机 装饰器有什么用?增强函数的功能 装饰器使用场景增加被装饰函数的行为代码复用 一个函数接收另一个函数作为参数,这种函数称之为高阶函数. 函数的重要特性 1.在python中,一切皆为对象,所以函数也是一个对象,从而函数可以赋值给变量. 定义一个add函数,函数的功能是实现两个数相加 系统为函数分配了一个内存地址:0x00000000021B3798 2.一个函数可以作为

  • Python进阶学习修改闭包内使用的外部变量

    目录 修改闭包内使用的外部变量 错误示例: 小结 闭包与闭包中修改外部变量 修改外部函数的变量 修改闭包内使用的外部变量 错误示例: # 定义一个外部函数 def func_out(num1): # 定义一个内部函数 def func_inner(num2): # 这里本意想要修改外部num1的值,实际上是在内部函数定义了一个局部变量num1 num1 = 10 # 内部函数使用了外部函数的变量(num1) result = num1 + num2 print("结果是:", resu

  • Python面向对象编程中的类和对象学习教程

    Python中一切都是对象.类提供了创建新类型对象的机制.这篇教程中,我们不谈类和面向对象的基本知识,而专注在更好地理解Python面向对象编程上.假设我们使用新风格的python类,它们继承自object父类. 定义类 class 语句可以定义一系列的属性.变量.方法,他们被该类的实例对象所共享.下面给出一个简单类定义: class Account(object): num_accounts = 0 def __init__(self, name, balance): self.name =

  • Python面向对象编程之类的进阶

    目录 1.引用的概念 2.对象的拷贝 2.1实例方法的引用 2.2类的特性装饰器 3.类的名称修饰 3.1_单下划线开头的名称修饰 3.2_单下划线结尾的名称修饰 3.3__双下划线开头的名称修饰 3.4__name__双下划线开头和结尾的名称修饰 3.5单下划线 4.Python的最小空类 1.引用的概念 引用 (Reference)是对象的指针 引用是内存中真实对象的指针,表示为变量名或者内存地址 每个对象存在至少一个引用,id()函数用于获得引用 在传递参数和赋值时,Python传递对象的

  • Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】

    本文实例讲述了Python面向对象程序设计OOP.分享给大家供大家参考,具体如下: 类是Python所提供的最有用的的工具之一.合理使用时,类可以大量减少开发的时间.类也在流行的Python工具中使用,例如,tkinter GUI API. 为何使用类 与面向对象的Java一样,类是对现实世界的一种抽象. 从更具体的程序设计观点来看,类是Python的程序组成单元,就像函数和模块一样:类是封装逻辑和数据的另一种方式.实际上,类也定义新的命名空间,在很大程度上就像模块.但是类有三个重要的独到之处,

  • Python面向对象之类和实例用法分析

    本文实例讲述了Python面向对象之类和实例用法.分享给大家供大家参考,具体如下: 类 虽然 Python 是解释性语言,但是它是面向对象的,能够进行对象编程.至于何为面向对象,在此就不详说了.面向对象程序设计本身就很值得深入学习,如要了解,请参阅网上其他的资料. 面向对象最重要的概念就是类(Class)和实例(Instance),牢记 类 是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. 以Studen

  • Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】

    本文深入分析了Python面向对象程序设计OOP.分享给大家供大家参考,具体如下: 下面是一个关于OOP的实例,模块文件为person.py # File person.py(start) class Person: def __init__(self, name, job=None, pay=0): self.name = name self.job = job self.pay = pay def last_name(self): return self.name.split()[-1] d

随机推荐