目录
1、数据类型
python 中数据类型与c++中基本相同
"""
python 数据类型
"""
# 整数
print(123)#字面量
a=123
print(a)#变量
# 浮点数
print(1.2)
b=1.2
print(b)#变量
# 字符串
print("Hello,world!!!") #字面量
c="Hello,world"
print(c)#变量
type_int=type(123)#返回数据类型
print(type_int)
# 小结:python中变量是没有类型的,但是变量存储的数据是有类型的
需注意python中变量是没有类型限制的,但变量所存储的数据是有类型的 ;
2、数据类型转换
c++中除了强制类型转换以外,常用的几个类型转换函数:stoi(),atoi(),to_string()等等(需包含头文件#include<string>
python中个人感觉更便捷:
"""
数据类型转换
"""
str1=str(123)
str2=str(1.23)#数据类型转字符串
num1=int("123")
print(type(num1),num1)
num2=int(1.23)#丢失精度
print(type(num2),num2)
num3=float(123)
print(type(num3),num3)
# 小结:万物皆可转字符串,只有数字字符串可以转数字类型
其中注意只有数字字符串可以由字符串转数字类型;
3、数学运算符
c++与python中+、-、*的用法是一样的,不同在于/的用法:
print("5/2=%.2f"%(5/2))
5/2=2.50
c++中/是整除,而python中整除符号是//,/则是正常意义上的除号;
此外python中幂运算符号是**,而c++中则要使用pow()函数;
以此类推复合运算符:+=,-=,*=,**=,/=,//=
4、字符串拓展
字符串拼接写法与c++中有差异:
"""
字符串拓展
"""
#1、字符串拼接
# + 拼接
print("你好"+"世界")
name="Ethan"
print("My name is "+name)
#字符串格式化拼接
age=22
print("My age is %d"%age)#占位符
message="My name is %s,age is %s"%(name,age)
print(message)
print(f"My name is {name},age is {age}")#f:format 直接格式化
5、判断、循环语句
需注意python中用:表示循环开始,使用缩进来表示从属关系,而不是c++中使用的{};
其次c++中语句条件需写在()内,而python不需要;
"""
Python 各语句运用
"""
#input()
name=input("请告诉我你的名字:")
print("我知道了,你是%s"%name)
#判断语句
a=10
if a==5:
print("bingo!")
elif a==10:
print("ohhh")
else:
print("sorry~")
print("判断语句已结束")
#循环语句
i=0
while i<3:
i+=1
print("第%d次输出"%i)
for i in name:
print(i)
#range函数 range(num1,num2,step):以step为步长,从num1(包含)开始,到num2(不包含)得到一个数字序列
for i in range(10):
print(i)
# 小结:python中通过缩进关系判断从属关系;
# for循环无法定义循环条件,只能被动取出数据进行处理
6、函数用法
python中函数无需指定返回值类型(这和定义变量应该是一个道理),同时python中有一个特殊的的字面量None,用以表示空,类似c++中的void
"""
函数的定义用法
def 函数名(传入参数):
函数体
return 返回值
函数使用步骤:先定义,再使用(参数和返回值不需要的话可以省略)
"""
def sayHello():
print("Hello!")
return None
result=sayHello()
print(f"无返回值的函数返回值是{result},其类型是{type(result)}")
Hello!
无返回值的函数返回值是None,其类型是<class 'NoneType'>
综合应用案例:ATM程序实现
money=50000
name="Ethan"
def check_deposit():
print("-----查询-----")
print("您的账户余额还有:%d"%(money))
def add_deposit(add_money):
print("-----存款-----")
global money #在函数内部定义为全局变量
money+=add_money
print("您的账户余额还有:%d"%(money))
def get_deposit(get_money):
print("-----取款-----")
global money
money-=get_money #在函数内部定义为全局变量
print("您的账户余额还有:%d"%(money))
def ATM_order():
print("-----欢迎使用ATM机!-----")
flag=int(input("1:查询余额\n2:存款\n3:取款\n请输入您想办理的业务:"))
if flag==1:
check_deposit()
elif flag==2:
add_money=int(input("您要存多少钱:"))
add_deposit(add_money)
elif flag==3:
get_money=int(input("您要取多少钱:"))
get_deposit(get_money)
else:
print("你输入了个啥?%d"%(flag))
while True:
client_name=input("请输入您的姓名:")
if client_name!=name:
print("姓名错误!程序自动退出。")
break
ATM_order()
flag=int(input("是否退出程序?\n1:是\n0:否\n"))
if flag:
break
注意:全局变量在函数变量中需要先进性声明
7、数据容器
(1)list(列表)
"""
数据容器
"""
my_list=["Ethan",666,99.99,[1,2,"hello"]]
print(my_list)
print(my_list[3][2])
['Ethan', 666, 99.99, [1, 2, 'hello']]
hello
python列表中数据类型不受限制,可以多种组合
(2) tuple(元组)
元组可以理解成只读的列表,用()或tuple()函数定义;
my_tuple=("Ethan",666,99.99,[1,2,"hello"])
print(my_tuple)
my_single_tuple=("Ethan",)#只有单个元素的元组必须加个逗号
wrong_tuple=("Ethan")
print(f"不加逗号时的类型是:{type(wrong_tuple)}")
('Ethan', 666, 99.99, [1, 2, 'hello'])
不加逗号时的类型是:<class 'str'>
(3)string(字符串)
字符串内部只能存储字符,且内部元素也不可修改,使用" "或者str()函数定义
(4)序列
以上所述的三种容器:列表,元组,字符串都属于序列
序列的切片(语法):序列[起点:终点:步长]
name="Ethan"
s_name=name[:3:1]#起点默认为0,不包含终点
r_name=name[2::-1]#步长为负数,倒序
print(s_name,r_name)
Eth htE
(5)set(集合)
与以上三种数据容器不同,集合内部的数据是无序的,且不支持重复元素,使用{ }或者set()函数定义
由于集合内部无序,无法用下标进行索引,所以只支持for循环进行遍历
(6)dict(字典)
类似c++中的map,键值对应,定义方法:{key1:value1,key2:value2}
其中key不允许重复,重复写相当于覆盖,能通过key访问对应的value
my_dict={"name":"Ethan","age":22,"sex":"man"}
for i in my_dict:
print(i,":",my_dict[i])#默认遍历的i是key
name : Ethan
age : 22
sex : man
(7)各数据容器对比
各容器共同点:都可以遍历(for)
各容器通用方法:len(容器),max(容器),min(容器),sorted(容器,reverse=False)其返回值是列表(字典会损失value值)
五种容器都可以转换为列表,元组,字符串,集合四种类型之一,即:list(),tuple(),str(),set();但是非字典类型无法转化为字典(无法凭空变出value值),字典类型变为其他四种类型时只保留key值
8、函数进阶
(1)函数的多返回值
def my_func():
return 1,2#通过return语句返回多个返回值
a,b=my_func()#多个变量对位接收返回值即可
print(a,b)
1 2
(2)函数的多种传参方式
函数有4种常见参数使用方式:位置参数,关键字参数,缺省参数,不定长参数;
首先是位置参数和关键字参数:
def get_info(name,age,gender):
print(f"Name is {name},age is {age},gender is {gender}")
get_info("Ethan",22,"man")#位置参数即和C++一样的传参方式,形参和实参一一对应
get_info(name="Ethan",gender="man",age=22)#关键字参数类似键值对,可以不按照形参顺序传入参数
# get_info(22,name="Ethan",gender="man")#关键字参数可以和位置参数昏庸,但位置参数必须在前且匹配形参顺
# TypeError: get_info() got multiple values for argument 'name'
get_info("Ethan",age=22,gender="man")#关键字参数可以和位置参数昏庸,但位置参数必须在前且匹配形参顺
Name is Ethan,age is 22,gender is man
Name is Ethan,age is 22,gender is man
Name is Ethan,age is 22,gender is man
缺省参数即默认参数,和C++用法是相同的 ;
不定长参数也叫可变参数,用于不确定调用参数的时候会传递多少个参数的场景;
不定长参数可以使用位置传递,也可以使用关键字传递:
def get_info(*args):#位置传递
print(args)#arg是一个元组
def Get_info(**kwargs):#关键字传递
print(kwargs)#kwargs是一个字典
get_info("Ethan",22,"man")
Get_info(name="Ethan",age=22,gender="man")
#小结:位置不定长用*,关键字不定长用**
('Ethan', 22, 'man')
{'name': 'Ethan', 'age': 22, 'gender': 'man'}
(3)匿名函数
#def关键字可以定义带有名称的函数(可以重复使用)
#lambda关键字则可以定义匿名函数(只能使用一次)
#上面的函数也可以简写成:
my_func(lambda a,b:a+b)
注意:lambda函数的函数体只能有一行代码,多行代码不能使用lambda函数
9、文件读写
使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
f=open("C:\A_MyProgram\Vscode\测试.txt","w",encoding="UTF-8")#endoding位置不是第三位,所以只能用关键字的方式传参
#此处的f是一个open函数创建的一个文件对象
print(type(f))
#<class '_io.TextIOWrapper'>
10、异常捕获
try:
可能发生错误的代码
except:这里可以加类型名,如果不加的话默认捕获所有异常
如果出现异常执行的代码
else:
没有异常时执行这段代码
finally:
无论有没有异常都会执行这段代码
11、python模块
(1)模块的导入方式
注意:*表示引入模块内的全部内容
通过.使用模块内部的功能
(2)自定义模块
其实就是自己创建一个.py文件,就相当于一个模块
__main__变量的作用:用于判断内置变量__name__的值,即判断当前运行的程序是否是直接执行的,可以防止module中调用的函数在module被导入的时候自动执行;
__all__变量的作用:__all__变量是一个列表,用于记录可以被*导入的函数、变量等等,如果一个模块文件中有__all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素,注意:这个__all__变量只作用于*,可以手动导入其它变量
"""创建一个module"""
__all__=['say_hello']
def say_hello():
print("hello")
def say_bye():
print("bye")
if __name__=="__main__":
say_hello()
# hello
from demo6 import *
say_hello()
# say_bye()
# NameError: name 'say_bye' is not defined
12、python包
如果说模块相当于文件,那么包就相当于一个文件夹,但这个文件夹里必须包含一个__init__.pyd的文件,这样这个文件夹才是一个python包
使用:
import 包名.模块名
第三方包安装:通过pip安装
13、python面向对象编程
首先是类的创建,除了语法有差异,其余和C++没啥区别:
首先介绍一下python类内置的常见的五种方法,内置的方法也称魔术方法:
class Student:
name=None
age=None
def __init__(self,name,age) -> None:#构造方法
self.name=name
self.age=age
pass
def __str__(self) -> str:#字符串方法
return (f"Student类对象,姓名是{self.name},年龄是{self.age}")
pass
def __lt__(self,other):#用于实现小于符号或大于在对象间的使用
return self.age<other.age
#__le__用于实现大于等于和小于等于在对象间的使用
#同理__eq__方法用于实现==符号
s=Student("Ethan",22)
print(s.name)
# Ethan
print(s.age)
# 22
print(s)#字符串方法将对象转为字符串
# Student类对象,姓名是Ethan,年龄是22
s1=Student("Lydia",21)
if s1<s:#这个魔术方法应该就是内部将<符号进行了重载
print(f"{s.name}比{s1.name}大")
else:
print(f"{s.name}比{s1.name}小")
# Ethan比Lydia大
(1)封装
Python的封装是面向对象编程的重要概念之一,它允许开发者对数据和方法进行封装,以保护数据的安全性和减少代码的耦合性。Python的封装语法包括以下三个关键词:
-
public:公有的,使用该关键字声明的属性和方法可以被外部访问。
-
private:私有的,使用该关键字声明的属性和方法只能在类的内部访问。
-
protected:受保护的,使用该关键字声明的属性和方法可以被继承类访问。
在Python中,使用下划线“_”来表示属性和方法的可见性,其具体用法如下:
-
private_var:使用双下划线“”开头的属性表示私有属性,只能在类的内部访问。
-
protected_var:使用单下划线“”开头的属性表示受保护属性,可以被继承类访问。
-
public_var:默认情况下,没有使用下划线开头的属性都是公有属性,可以被外部访问。
同样地,方法也可以使用相同的方式来表示可见性,如下:
-
private_method():使用双下划线“”开头的方法表示私有方法,只能在类的内部调用。
-
protected_method():使用单下划线“”开头的方法表示受保护方法,可以被继承类调用。
-
public_method():默认情况下,没有使用下划线开头的方法都是公有方法,可以被外部调用。
注意,在Python中使用封装并不能完全保证数据的安全性,因为Python允许通过特定的方式来访问私有属性和方法,这也是Python的一种灵活性。但是,使用封装可以减少代码的耦合性,使代码更易于维护和扩展。
class Car:
def __init__(self, make, model, year):
self._make = make # 受保护属性
self._model = model # 受保护属性
self.__year = year # 私有属性
def get_make(self):
return self._make
def get_model(self):
return self._model
def get_year(self):
return self.__year
def set_year(self, year):
if year < 1900:
print("Invalid year!")
else:
self.__year = year
car1 = Car("Toyota", "Corolla", 2018)
print(car1.get_make()) # 输出 "Toyota"
print(car1.get_model()) # 输出 "Corolla"
print(car1.get_year()) # 输出 2018
# 无法直接访问私有属性 "__year"
# print(car1.__year)
# 修改私有属性 "__year" 的值
car1.set_year(2020)
print(car1.get_year()) # 输出 2020
# 修改 "__year" 为无效值
car1.set_year(1899) # 输出 "Invalid year!"
print(car1.get_year()) # 输出 2020
(2)继承
Python中的继承语法允许一个类从另一个类中继承属性和方法。在Python中,继承是通过在类定义中指定父类来实现的。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} is speaking")
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
def speak(self):
super().speak()
print(f"{self.name} is meowing")
cat1 = Cat("Tom", "white")
cat1.speak() # 输出 "Tom is speaking" 和 "Tom is meowing"
和C++的区别:
-
Python中没有访问修饰符。在Python中,类的属性和方法都可以从类的外部访问,因为它们默认是公共的。在C++中,可以使用访问修饰符(public、protected和private)来限制成员变量和成员函数的访问范围。
-
Python中的继承语法更加简单明了。在Python中,可以使用
class SubClass(BaseClass)
的形式轻松地声明一个子类继承自一个父类。而在C++中,需要使用不同的关键字(public、protected和private)来声明继承方式(公有继承、保护继承和私有继承)。 -
Python中的多态是动态的。在Python中,方法的调用是动态绑定的,这意味着它会根据对象的实际类型来调用方法。而在C++中,方法的调用是静态绑定的,这意味着它会根据对象的声明类型来调用方法。
-
Python中的析构函数不是必须的。在Python中,对象的垃圾回收是由解释器自动处理的,因此不需要定义析构函数。而在C++中,析构函数是必须的,因为对象的内存管理是由程序员负责的。
总体来说,Python相对于C++来说更加简洁,语法更加灵活,并且不需要像C++那样考虑内存管理问题。但是,C++在性能方面更有优势,并且支持更多的编程范式,如泛型编程和模板元编程。
下面是一段C++的代码:
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Animal is eating" << endl;
}
protected:
void sleep() {
cout << "Animal is sleeping" << endl;
}
};
class Cat : public Animal {
public:
void meow() {
cout << "Cat is meowing" << endl;
}
};
int main() {
Cat cat;
cat.eat(); // 公有成员函数可以从类外访问
cat.meow();
// cat.sleep(); // 受保护成员函数不能从类外访问
return 0;
}
(3)多态
同样的行为(函数),传入不同的对象,得到不同的状态
class Animal:
def speak(self):
pass
class Cat(Animal):
def speak(self):
print("喵喵喵")
class Dog(Animal):
def speak(self):
print("汪汪汪")
def animal_speak(animal):
animal.speak()
cat=Cat()
dog=Dog()
animal_speak(cat)
# 喵喵喵
animal_speak(dog)
# 汪汪汪
与 Python 不同的是,C++ 的多态是静态类型的多态,即在编译时确定函数调用的实际类型。而 Python 是动态类型的多态,即在运行时根据实际类型确定函数调用。此外,Python 中的多态不依赖于特定的语法机制,而是通过对象的行为来实现的。这也是 Python 的灵活性和简洁性的一个重要体现。
下面是C++中的多态实现,用以对比学习:
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() {
cout << "Drawing a shape." << endl;
}
};
class Rectangle : public Shape {
public:
void draw() {
cout << "Drawing a rectangle." << endl;
}
};
class Circle : public Shape {
public:
void draw() {
cout << "Drawing a circle." << endl;
}
};
int main() {
Shape* shape1 = new Rectangle();
Shape* shape2 = new Circle();
shape1->draw();
shape2->draw();
delete shape1;
delete shape2;
return 0;
}