Python基础

100 阅读10分钟

数据

一、内建原子数据类型

1、整型 int
2、浮点型 float
3、数学运算符 
+ - * / 
**(幂) %(模) / /(整除)
注意:当两个整数相除的结果是一个浮点数时,只返回商的整数部分
4、布尔类型
true false
5、布尔运算符
and or not
6、标识符
以字母或下划线卡头
7、赋值语句
theSum = 0

二、内建集合数据类型

有序集合:列表、字符串、元组
无序集合:集[set]、字典

1.列表:

是零个或多个指向Python数据对象的引用的有序集合,通过方括号内以逗号分隔的形式来表达,空列表就是[]。列表是异构的,所以其指向的数据对象不需要是同一个类,例如:[1,2,true,3.4],并且这一集合可以被赋值给一个变量。

image.png 普通示例:

>>> myList = [1, 2, true, 3.4]
>>> A = [myList] * 3
>>> A
[[1, 2, true, 3.4], [1, 2, true, 3.4], [1, 2, true, 3.4]]
>>> myList[2] = 45
>>> A
[[1, 2, 45, 3.4], [1, 2, 45, 3.4], [1, 2, 45, 3.4]]

切片示例:

切片[开始索引,结束索引,截取的间隔距离]
>>> B = [1, 2, 3, 4]
>>> C = B[1::3]
>>> C
[2, 3]
>>> D = B[-1::-2]
>>> D
[4, 2]

image.png _add_(两数之和)

>>> (54)._add_(21)
75

range(生成一个代表值序列范围对象,使用list函数,可以以列表的形式看到范围对象的值)

>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(5, 10, 2))
[5, 7, 9]
>>> list(range(10 ,1, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2]

2.字符串:

是零个或多个字母、数字和其他符号的有序集合,常量字符串值通过单引号或双引号与标识符进行区分。由于字符串是序列,所以所有序列运算符都能用于字符串。

image.png

>>> myName = 'David'
>>> myName.split('v')
['Da', 'id']

3.修改性

列表和字符串的主要区别在于,列表可以被修改,字符串不可以。列表的这一特性称为可修改性

4.元组

元组与列表非常相似,但元组和字符串一样是不可修改的。元组的格式为(1, "cat", true),如果尝试对元组做任何操作,都会报错。

5.集(set)

集是由零个或多个不可改变的数据对象组成的无序集合,他不允许重复元素,格式为{1, "cat", true}。集是异构的,可以赋给变量。

>>> myTest = {1, "cat", true}
>>> myTest
{1, "cat", true}

image.png image.png

5.字典

字典是一个无序结构,每对元素都由一个键和一个值组成,也就是键值对的形式。格式为:{'name':'张三'}

image.png

>>> phoneext={'david':1410, 'brad':1137}

>>> phoneext.items()
dict_items([('brad', 1137), ('david', 1410)])

>>> list(phoneext.items())
[('brad', 1137), ('david', 1410)]

输入和输出

一、输入

input

input函数接收一个字符串作为参数,他的值返回的也是一个字符串。如果需要将这个字符串转换成其他类型,则必须明确地提供类型转换,否则会报错。

sradius = input("Please enter the radius of the circle ")
radius = float(sradius)
diameter = 2 * radius

二、输出

print

默认分隔符为一个空格,可以通过sep更改分隔符,通过end改变结尾。

>>> print("Hello","World", sep="***")
Hello***World

>>> print("Hello","World", end="***")
Hello World***

三.格式化修饰符

格式化字符串是一个模板,其中包含保持不变的单词或空格,以及之后插入的变量的占位符。Python 的字符串还包含了一个format 方法。该方法可以与新的 Formatter 类结合起来使用,从而实现复杂字符串的格式化。

image.png image.png

>>> price = 24
>>> item = "banana"
>>> print("The %s costs %d cents" % (item,price))
The banana costs 24 cents

控制结构(迭代和分支)

一、迭代

while和for

>>> counter = 1
>>> while counter <= 5:
... print("Hello, world")
... counter = counter + 1
...
Hello, world 
Hello, world
Hello, world
Hello, world
Hello, world

>>> for item in range(5):
... print(item**2)
...
0
1
4
9
16
>>>

一、分支

ifelse和if、elif

if n < 0:
print("Sorry, value is negative")
else:
print(math.sqrt(n))

if n < 0:
n = abs(n)
print(math.sqrt(n))

if score >= 90:
print('A')
elif score >= 80:
print('B')
else:
print('C')

二、列表解析式

列表可以通过使用迭代结构和分支结构来创建,这种方式被叫做列表解析式。

通过for语句生成列表

>>> sqlist = []
>>> for x in range(1,11):
sqlist.append(x*x)
>>> sqlist
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

异常处理

try except

可以在try语句块中调用print函数来处理异常,except会”捕捉“到异常,还可以使用raise来触发运行的异常。

>>> anumber = int(input("Please enter an integer "))
Please enter an integer -23

>>> try:
           print(math.sqrt(anumber))
      except:
           print("Bad Value for square root")
           print("Using absolute value instead")
           print(math.sqrt(abs(anumber)))

Bad Value for square root
Using absolute value instead
4.79583152331
>>>
>>> if anumber < 0:
...       raise RuntimeError("You can't use a negative number")
... else:
...       print(math.sqrt(anumber))
...

Traceback (most recent call last):
File "<stdin>", line 2, in <module>
RuntimeError: You can't use a negative number
注意:除了 RuntimeError 以外,还可以抛出很多不同类型的异常。

定义函数

函数的定义需要一个函数名、一系列的参数以及一个函数体,函数也可以显示地返回一个值。

>>> def square(n):
...         return n**2
...
>>> square(3)
9
>>> square(square(3))
81

Python面向对象编程:定义类

Python是一门面向对象的编程语言,面向对象编程语言最强大的一项特性就是允许创建一个全新的类来对所需的数据进行建模。每当我们需要实现抽象数据类型时,就可以创建新类。

实现Fraction类

要展示如何实现用户定义的类,一个常用的例子是构建实现抽象数据类型Fraction类,也就是创建一个“看上去很像”分数的数据对象。上面的值称作分子,可以是任意整数;下面的值称作分母,可以是任意大于0的数(负的分数带有负的分子)。

// 定义Fraction类
class Fraction:

类的构造方法

(1)_init_

我们可以对Fraction进行加减乘除等运算。在Python中,构造方法总是命名为_init_,那么Fraction类及其构造方法如以下例子:

class Fraction:
    // self是一个总是指向对象本身的特殊参数,他必须是第一个形参,但是调用方法时,从来不需要提供相应的实际参数。
    def _init_(self, top, bottom):
        self.num = top
        self.den = bottom
        
// 要创建Fraction类的实例,必须调用构造方法,使用类名并且传入状态的实际值就能完成调用,但不能直接调用_init_
myFraction = Fraction(3, 5)
print(myFraction)
<_main_.Fraction instance at 0x409blacc>
// 这里的输出是因为myFraction并不知道如何相应打印请求,myFraction唯一能做的就是显示存储在变量中的实际引用,也就是地址本身。

(2)show方法

对于上述不能正确打印的行为,我们可以通过show方法来解决这个问题。

def show(self):
     print(self.num, "/", self.den)

>>> myFraction = Fraction(3, 5)
>>> myFraction.show()
3/5
>>> print(myFraction)
<_main_.Fraction instance at 0x409blacc>

(3)_str_方法

Python的所有类都提供了一套标准方法,但可能没有正常工作。其中之一就是将对象转化成字符串的方法_str_。这个方法的默认实现是返回实例的地址字符串,所以我们需要重写默认实现,或者说是重新定义该方法的行为。

新的方法通过将两部分内部状态转化成字符串并在他们之间插入字符“/”来将分数对象转化成字符串。

def _str_(self):
    return str(self.num) + "/" + str(self.den)
    
>>> myFraction._str_()
'3/5'

(4)_add_方法

如果我们定义两个分数,并让他们相加,则会报错。因为加号是无法处理Fraction的操作数的,那么我们可以通过重写Fraction类的_add_方法来修正这个错误。

def _add_(self, otherFraction):
    newNum = self.num * otherFraction.den + \
                self.den * otherFraction.num
    newDen = self.den * otherFraction.den
    return Fraction(newNum, newDen)

>>> f1 = Fraction(1, 4)
>>> f2 = Fraction(1, 2)
>>> f3 = f1 + f2
>>> print(f3)
6/8

(5) gcd函数

虽然重写后的Fraction确实实现了相加,但是得到的结果并不是一个最简分数,我们可以通过定义一个gcd函数,寻找最大公因数来化简分数。

def gcd(m, n):
    while m % n !=0:
        oldM = m
        oldN = n
        
        m = oldN
        n = oldM % oldN
    return n

(6) 改良版_add_方法

对于分数6/8,最大公因数是2,我们可以通过gcd函数拿到最大公因数。这时,我们就可以将_add_方法进行改良。\ 被叫做续行符,当一条Python语句被分成多行时,需要用到续行符。

def _add_(self, otherFraction):
    newNum = self.num * otherFraction.den + \
                self.den * otherFraction.num
    newDen = self.den * otherFraction.den
    common = gcd(newNum, newDen)
    return Fraction(newNum//common, newDen//common)
 
>>> f1 = Fraction(1, 4) 
>>> f2 = Fraction(1, 2)
>>> f3 = f1 + f2
>>> print(f3)
3/4

(7)_eq_方法

假设有两个Fraction对象,f1和f2。只有在他们是同一个对象的引用时,f1===f2才为true,这被称为浅相等。所以分子分母相同的两个不同的对象是不相等的。 image.png 所以我们可以通过重写_eq_方法建立深相等,即根据值来判断相等,而不是根据引用。_eq_是一个标准方法,他会比较两个对象,在他们值想等的时候返回true,否则返回false。 image.png

def _eq_(self, other):
    firstNum = self.num * other.den
    secondNum = other.num * self.den
    return firstNum == secondNum

(8)Fraction最终的完整实现

class Fraction:
    def _init_(self, top, bottom):
        self.num = top
        self.den = bottom
    def _str_(self):
        return str(self.num) + '/' + str(self.den)
    def show(self):
        print(self.num, '/', self.den)
    def _add_(self, otherFraction):
        newNum = self.den * otherFraction.den + \
            self.den * otherFraction.num
        newDen = self.den * otherFraction.den
        common = gcd(newNum,newDen)
        return Fraction(newNum//common,newDen//common)
    def _eg_(self, other):
        firstNum = self.num * other.den
        secondNum = self.den * other.num
        return firstNum = secondNum

继承和逻辑门

继承

继承使一个类与另一个类相关联,就像孩子从父母那里继承了特性。与之相似的,Python中的子类可以从父类继承特征数据和行为。父类也称为超类

列表、字符串和元组都是有序集合,他们都继承了共同的数据组织和操作,但他们之间的区别可以根据数据是否同类以及集合是否可修改来判断,这就是子类从父类继承了共同的特征,但又存在不同的特性彼此区分。

因此,我们将列表、元组等称为,有序集合称为,他们之间的关系被称为IS-A关系。例如,一只狗是一种动物,因此狗IS-A动物。这种关系可以通过继承来实现。 image.png HAS-A关系表示一个对象具有另一个对象作为其属性或成员,这种关系也被称为组合或聚合关系。例如,一辆汽车具有一个引擎,因此汽车HAS-A引擎。这种关系可以通过在类中创建一个成员变量来实现。

总的来说,IS-A关系是一种继承关系,表示一种类型与另一种类型之间的关系;而HAS-A关系是一种组合关系,表示一个对象具有另一个对象作为其属性或成员,HAS-A不需要继承。

逻辑门

逻辑门是这个模拟程序的基本构造单元,它们代表其输入和输出之间的布尔代数关系。一般来说,逻辑门都有单一的输出,输出值取决于提供的输入值。

与门(AND gate)

与门有两个输入,每一个都是0或1(分别代表false和true)。如果两个输入都是1,那么输出就是1;如果至少有一个输入是0,那么输出就是0。

或门(OR gate)

同样有两个输入,当至少有一个输入为1时,输出就是1;当两个输入都是0时,输出是0。

非门(NOT gate)

非门只有一个输入,输出与输入刚好相反。如果输入是0,那么输出就是1;如果输入是1,输出则为0。

下图展示了每种逻辑门的表示方法,并且每种都有一张真值表,用于展示输入和输出的对应关系。

image.png