Python

异常处理

except从句可以专门处理单一的错误或异常。如果没有给出错误或异常的名称,它会处理所有的错误和 异常。对于每个try从句,至少都有一个相关联的except从句。

添加如下测试代码:

while True:
    try:
        n = input("请输入一个整数: ")
        n = int(n)
        print("输入成功!")
        break
    except ValueError as e:
        print("无效数字,再次输入 ...",e)

上面的代码,我们通过“while True:”来构建一个死循环,循环内部通过input来接收用户的输入,通过 int(n)来将用户输入转换为整数,如果输入的不是一个整数,这会引发ValueError异常,利用“except ValueError as e”来捕获这个异常。如果输入是整数,直接调用“break”,会跳出while循环,执行最后的 print,程序退出。运行结果如下:

面向对象

类与对象

在python中,我们使用class关键字来定义一类事物,类是一个抽象描述,并不是真正的存在,需要把它 初始化才会产生一个真正的事物,我们称之为对象。在编程过程中,拥有行为和数据的是对象,而不是 类。

下面我们声明一个简单的类:

# -*- coding: UTF-8 -*- 
class Person:
    pass# An empty block 
p = Person()
print(p)

我们使用class语句后跟类名,创建了一个新的类。这后面跟着一个缩进的语句块形成类体。在这个例子 中,我们使用了一个空白块,它由pass语句表示。接下来,我们使用类名后跟一对圆括号来创建一个对 象/实例。为了验证,我们简单地打印了这个变量的类型。它告诉我们我们已经在main模块中有了一个 Person类的实例。结果如下:

#main.Person object at 0x10a13f630>

你可能已经注意到存储对象的计算机内存地址也打印了出来。这个地址在你的计算机上会是另外一个 值,因为Python可以在任何空位存储对象。

对象的方法

方法代表现实世界中的行为,简单示例如下:

class Person1:
    
    def sayHi(self):
        print('Hello, how are you?')
p1 = Person1()
p1.sayHi()
# 这里我们需要注意sayHi方法没有任何参数,但仍然在函数定义时有self,self代表对象本身,等价
于C++中的self指针和Java、C#中的this引用。之后,我们通过对象名加点的方式来调用对象的方法。
运行结果如下:
# Hello, how are you?

构造函数

我们在使用类来构造一个对象的时候,通常在构造之初需要把对象本身的关键属性进行初始化。比如初 始化一个人,如果我们认为年龄和名字是关键属性的话,我们在实例化这个人的时候,需要把相关属性 的值传进来。上面我们知道初始化对象的时候是类名加括号的方式,实际上这个括号调用了一个内置的 方法,我们称之为构造函数,正是该函数返回了被初始化的对象本身。

python的构造函数名为init,我们可以自定义传入参数的类型和个数。示例如下:

class Person2:
    name = "zs"
    
    def __init__(self, name):
        self.name = name    
    def sayHi(self):
        print('Hello, my name is', self.name)
        
p2 = Person2('666')
p2.sayHi()

这里,我们把init方法定义为取一个参数name(以及普通的参数self)。在这个init里,我们只是创建一 个新的字段 name。最重要的是,我们没有专门调用init方法,只是在创建一个类的新实例的时候,把参 数包括在圆括号内跟在类名后面,从而传递给init方法。

现在,我们能够在我们的方法中使用self.name变量,这在sayHi方法中得到了验证,运行结果如下:

Hello, my name is 666

变量

变量代表属性和数据。在python中变量有两种,类变量和对象变量。类变量是全局的,对每个对象都共 享,对象的变量是实例化的,每个对象之间互不影响。下面我们通过一段代码来对比:

class Person3:
    '''Represents a person.'''    
    population = 0
    
    def __init__(self, name):
        '''Initializes the person's data.'''        
        self.name = name        
        print( '(Initializing %s)' % self.name)
         # When this person is created, he/she        
            # adds to the population        
        Person3.population += 1  
        
    def sayHi(self):
        '''Greeting by the person.
       Really, that's all it does.'''        
        print('Hi, my name is %s.' % self.name)
        
     def howMany(self):
        '''Prints the current population.'''        
        if Person3.population == 1:
            print('I am the only person here.')
        else:
            print('We have %d persons here.' % Person3.population)
            
xh = Person3('xiaohong')
xh.sayHi()
xh.howMany()
kl = Person3('考拉')
kl.sayHi()
kl.howMany()
xh.sayHi()
xh.howMany()

这个例子略微有点长,但是它有助于说明类与对象的变量的本质。这里,population属于Person类,因 此是一个类的变量。name变量属于对象(它使用self赋值)因此是对象的变量。 观察可以发现init方法用一个名字来初始化Person实例。在这个方法中,我们让population增加1,这是 因为我们增加了一个人。同样可以发现,self.name的值根据每个对象指定,这表明了它作为对象的变量 的本质。 在这个程序中,我们还看到docstring对于类和方法同样有用。我们可以在运行时使用Person.doc和 Person.sayHi.doc来分别访问类与方法的文档字符串。 这里需要注意的是: Python中所有的类成员(包括数据成员)默认都是公有的。 如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称管理体系会有效地把它作 为私有变量。 这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将 作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀 不同)。

继承

继承这个概念,经常以父与子的关系来被阐述,我认为这阐述对初学者来说是一种误导。在人类社会 中,父与子继承的是什么?是财产,实际是赠予。面向对象的继承,实际是不是从现实世界中来,而是 为了解决面向对象编程的问题二产生的,要解决的是代码复用的问题。比如人类有许多共性,有鼻子, 有眼睛。但是人类也是分亚种的,从肤色上划分人种,地理上划分人群。那么在定义黄种人和黑种人的 时候,不可避免的要重新定义很多属性和行为,于是有了继承的概念,把公共的内容放到Person类里 面,然后AsiaPerson 继承Person类,它自然就有了Person类定义的内容,这种思想,其实换个词可能 更好理解——克隆。概念就不纠结了,理解就好,下面看代码:

class SchoolMember:
    '''Represents any school member.'''   
    def __init__(self, name, age):
        self.name = name        
        self.age = age       
        print('(Initialized SchoolMember: %s)' % self.name)
     def tell(self):
        '''Tell my details.'''       
        print('Name:"%s" Age:"%s"' % (self.name, self.age))
         
 class Teacher(SchoolMember):
    '''Represents a teacher.'''    
    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name, age)
        self.salary = salary       
print('(Initialized Teacher: %s)' % self.name)
     def tell(self):
        SchoolMember.tell(self)
        print('Salary: "%d"' % self.salary)
         
 class Student(SchoolMember):
    '''Represents a student.'''    
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks       
        print('(Initialized Student: %s)' % self.name)
     def tell(self):
        SchoolMember.tell(self)
        print('Marks: "%d"' % self.marks)
         
t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('xh', 22, 75)
print() # prints a blank line 
members = [t, s]
for member in members:
 member.tell() # works for both Teachers and Students

为了使用继承,我们把基类的名称作为一个元组跟在定义类时的类名称之后。然后,我们注意到基类的 init方法专门使用self变量调用,这样我们就可以初始化对象的基类部分。这一点十分重要——Python不 会自动调用基类的构造函数。调用基类的构造函数需要使用基类名进行调用,而且传入子类的self。

注意,在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student的实例仅仅作为 SchoolMember的实例。

另外,在这个例子中,我们调用了子类型的tell方法,而不是SchoolMember类的tell方法。可以这样来 理解,Python总是首先查找对应类型的方法,在这个例子中就是如此。如果它不能在导出类中找到对应 的方法,它才开始到基本类中逐个查找。

python支持多继承,可以同时继承多个基类。

相关推荐

  1. python

    2024-06-11 01:42:02       56 阅读
  2. python

    2024-06-11 01:42:02       57 阅读
  3. python

    2024-06-11 01:42:02       57 阅读
  4. python

    2024-06-11 01:42:02       44 阅读
  5. python

    2024-06-11 01:42:02       30 阅读
  6. <span style='color:red;'>python</span>

    python

    2024-06-11 01:42:02      29 阅读
  7. python

    2024-06-11 01:42:02       44 阅读
  8. <span style='color:red;'>Python</span>

    Python

    2024-06-11 01:42:02      29 阅读
  9. <span style='color:red;'>Python</span>

    Python

    2024-06-11 01:42:02      32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-11 01:42:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-11 01:42:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-11 01:42:02       82 阅读
  4. Python语言-面向对象

    2024-06-11 01:42:02       91 阅读

热门阅读

  1. 【CSP】202312-2 仓库规划

    2024-06-11 01:42:02       31 阅读
  2. 软件设计师笔记-计算机系统基础知识

    2024-06-11 01:42:02       27 阅读
  3. Reinforcement Learning学习(三)

    2024-06-11 01:42:02       30 阅读
  4. Rust-07-结构体

    2024-06-11 01:42:02       35 阅读
  5. Vue中的组件通信

    2024-06-11 01:42:02       33 阅读
  6. 前端面试题日常练-day62 【面试题】

    2024-06-11 01:42:02       29 阅读
  7. Android RadioButton+GridLayout实现多行多列的单选效果

    2024-06-11 01:42:02       32 阅读