第四章、数据类型
数据类型的作用:程序当中有很多数据,每一个数据都是有相关类型的,不同数据类型的数据占用空间大小不同。数据类型的作用就是指导PVM在运行程序的时候给数据在堆内存中分配多大的内存空间。
输出在控制台的都是字符串类型,会自动调用对象的__str__()方法
在 Python 中,数据类型可以分为两大类:基本数据类型(Primitive Data Types)和引用数据类型(Reference Data Types)。
一、基本数据类型(不可变)
基本数据类型是 Python 中的简单数据类型,它们是不可变的,即一旦创建后,其值不可修改。当进行某些操作时,会创建新的对象,而不是修改原有对象。Python 中的基本数据类型包括:
- 整数(int):表示整数值,例如
42
。 - 浮点数(float):表示浮点数值,例如
3.14
。 - 布尔值(bool):表示布尔类型,值为
True
或False
。 - 字符串(str):表示字符串类型,例如
'hello'
。 - 元组(tuple):使用圆括号
()
表示,一旦创建后,其内容不可修改。
1、不可变原理
基本数据类型是不可变的,主要是为了提高性能、安全性和一致性,以及满足 Python 设计哲学中的 "不可变性" 特性。
性能: 不可变对象在创建后其值不可更改,因此在使用时不需要为其分配额外的内存来处理可能的修改。这使得在操作这些类型的数据时更加高效,特别是对于字符串和整数等常用的数据类型。
安全性: 不可变性确保对象的值不会被意外更改。这在多线程环境下是非常重要的,因为多个线程可以同时访问和操作相同的数据。如果数据是可变的,可能会导致竞态条件(Race Condition)和不一致的结果。不可变性可以避免这类问题的发生,简化了线程之间的数据共享和同步。
一致性: 不可变性使得对象的值在其生命周期内保持不变,这在函数调用、数据传递和编程中的其他情况下非常有用。函数接收不可变对象作为参数时,可以确保函数内部不会改变传递进来的参数值,这有助于代码的可预测性和可维护性。
Python 设计哲学: Python 设计哲学之一是 "Simple is better than complex"(简单胜于复杂),不可变性使得 Python 语言在某些方面变得更简单、更容易理解。同时,Python 支持 "duck typing"(鸭子类型),允许开发者自由选择使用可变或不可变数据类型,从而根据实际需求灵活地处理数据。
综上所述,不可变性在 Python 中是一个重要的概念,它为代码的性能、安全性和一致性提供了许多好处,并符合 Python 设计的理念。
2、案例
整数(int):
x = 42
print(x) # 输出 42
# 修改整数的值
x = 99
print(x) # 输出 99
在上面的示例中,我们首先创建了一个整数对象 x
并将其赋值为 42
,然后将 x
的值修改为 99
。这是因为整数是不可变的,我们实际上是创建了一个新的整数对象 99
,而不是修改原来的对象。
字符串(str):
name = "Alice"
print(name) # 输出 "Alice"
# 修改字符串的值
name = "Bob"
print(name) # 输出 "Bob"
在上面的示例中,我们首先创建了一个字符串对象 name
并将其赋值为 "Alice"
,然后将 name
的值修改为 "Bob"
。同样,字符串是不可变的,我们实际上是创建了一个新的字符串对象 "Bob"
,而不是修改原来的对象。
元组(tuple):
t = (1, 2, 3)
print(t) # 输出 (1, 2, 3)
# 修改元组的值(不可行)
# t[0] = 10 # TypeError: 'tuple' object does not support item assignment
在上面的示例中,我们创建了一个元组对象 t
,并将其赋值为 (1, 2, 3)
。由于元组是不可变的,我们无法通过索引修改元组中的元素,尝试这样做会引发 TypeError
。
这些示例说明了整数、字符串和元组等数据类型的不可变性。当我们试图修改这些数据类型的值时,实际上是创建了新的对象,而不是在原有对象上进行修改。
二、引用数据类型(可变)
引用数据类型是用来存储对象的引用(内存地址),而不是直接存储对象本身的数据值。引用数据类型在赋值时实际上是复制对象的引用,而不是复制对象本身。以下是 Python 中的引用数据类型:
引用数据类型是 Python 中用于存储复杂数据的数据类型,它们是可变的,即可以在创建后修改其内容。这些数据类型实际上是对象的引用,而不是直接存储数据本身。修改引用数据类型的内容时,实际上是在操作对象本身,而不是创建新的对象。Python 中的引用数据类型包括:
- 列表(list):使用方括号
[]
表示,可以通过索引修改其中的元素。 - 字典(dict):使用花括号
{}
表示,可以通过键修改其中的值。 - 集合(set):使用花括号
{}
表示,可以添加、删除元素。
需要注意的是,Python 是一种动态类型语言,变量的类型是根据赋值的数据类型自动确定的。无论是基本数据类型还是引用数据类型,都可以使用简单的赋值语句创建变量,并在程序中使用它们。
1、可变原理
列表(list): 列表是由一系列有序元素组成的数据结构,使用方括号 []
表示。列表的元素可以通过索引进行访问、添加、删除和修改。例如:
my_list = [1, 2, 3]
print(my_list) # 输出 [1, 2, 3]
# 修改列表元素
my_list[0] = 10
print(my_list) # 输出 [10, 2, 3]
# 添加元素
my_list.append(4)
print(my_list) # 输出 [10, 2, 3, 4]
# 删除元素
my_list.remove(2)
print(my_list) # 输出 [10, 3, 4]
由于列表的内容可以修改,它被称为可变数据类型。
集合(set): 集合是一个无序的、不重复的元素集合,使用花括号 {}
表示。集合可以添加和删除元素。例如:
my_set = {1, 2, 3}
print(my_set) # 输出 {1, 2, 3}
# 添加元素
my_set.add(4)
print(my_set) # 输出 {1, 2, 3, 4}
# 删除元素
my_set.remove(2)
print(my_set) # 输出 {1, 3, 4}
由于集合的内容可以修改,它也被称为可变数据类型。
字典(dict): 字典是一种键-值对的数据结构,使用花括号 {}
表示。字典中的值可以通过键进行访问、添加、修改和删除。例如:
my_dict = {"name": "Alice", "age": 30}
print(my_dict) # 输出 {"name": "Alice", "age": 30}
# 修改值
my_dict["age"] = 31
print(my_dict) # 输出 {"name": "Alice", "age": 31}
# 添加键值对
my_dict["city"] = "New York"
print(my_dict) # 输出 {"name": "Alice", "age": 31, "city": "New York"}
# 删除键值对
del my_dict["name"]
print(my_dict) # 输出 {"age": 31, "city": "New York"}
由于字典的内容可以修改,它同样被称为可变数据类型。
可变数据类型在处理需要频繁插入、删除或修改元素的场景时非常有用,而不可变数据类型则更适用于那些需要保持数据不变性的场景。在编程中,根据需要选择合适的数据类型是非常重要的。
三、None类型
表示空值对象,由于Python中一切皆对象,因此为空值对象,
None空值对象是NoneType类的唯一实例对象
NoneType类是所有类的子类,因此可给任意数据类型赋值
在Python中,None
是一个特殊的数据类型,用于表示空值或缺失的值。它类似于其他编程语言中的 null
或 nil
。None
表示一个不存在的对象或变量,并且是Python的空值对象。
None
在Python中通常用于以下情况:
1、None类型用法
1、初始化变量
当你需要声明一个变量,但是还没有确切的值时,可以将其初始化为
None
。
x = None
2、返回空值
在函数中,如果没有明确的返回值,或者在某种情况下不需要返回任何值,可以使用
return None
来返回空值。
def do_something():
# 执行一些操作,但不需要返回值
return None
因为NoneType类型是在Python解释器中存在的,并不是真正的类型,所以使用None来表示NoneType类型,来指代None空值对象
在 Python 中,None
是一个特殊的常量,表示空值或空对象。它不是一个类型,而是一个对象。它通常用作函数没有明确返回值时的默认返回值,或者用作变量初始化时的默认值。在 Python 中,None
属于 NoneType
类型。
当一个函数的返回值类型被注释为 None
时,它表示该函数不返回任何值,或者说返回一个空值。这通常在函数没有明确返回值的情况下使用,或者在函数执行某些操作但不需要返回特定值时使用。例如,如果一个函数只是用来执行某些操作,而不需要返回任何结果,您可以将其返回类型注释为 None
。
在 Python 的类型注释中,函数的返回值注释应该是返回值的类型,而不是具体的返回值本身。None
作为特殊的常量表示空值,可以用作函数的返回值,同时它也是 NoneType
类型的唯一实例。因此,可以将函数的返回值类型注释为 None
表示函数没有返回任何有意义的值。
例如,当函数不需要返回特定值时,可以使用 None
作为返回值。在类型注释中,您可以使用 None
表示函数的返回类型为 None
,表示该函数不返回任何有意义的值。这种做法是为了提供对函数行为的清晰说明,而不是返回值本身。
下面是一个简单的示例,演示了函数的返回值注释为 None
的情况:
def log_message(message: str) -> None:
print(f"Log: {message}")
result = log_message("This is a log message")
print(result) # 输出为 None
在这个例子中,log_message
函数不返回任何有意义的值,它只是打印了日志消息。因此,函数的返回值被注释为 None
,表示它不会返回任何实际的值。
3、默认参数值
在函数定义时,可以将参数的默认值设置为
None
,以允许调用函数时不传递该参数。
def greet(name=None):
if name is None:
return "Hello, Guest!"
else:
return f"Hello, {name}!"
在这个例子中,greet
函数接受一个名为 name
的参数,并将其默认值设置为 None
。如果在调用函数时没有传递 name
参数,则使用默认值 None
。
2、None空值对象和NoneType类型的关系
None
是一个特殊的对象,它是Python中唯一的NoneType
对象。它不同于空字符串""
、空列表[]
或空字典{}
,这些都是不同类型的对象,表示不同的含义。在使用
None
时,要小心避免与其他类型的数据混淆。通常,当你需要表示空值或缺失的值时,可以使用None
。
None
和 NoneType
是两个不同的概念,但它们之间有关联。
1、None
:
None
是 Python 中表示空值或缺失的特殊对象。它是一个关键字,表示一个不存在的对象或变量。在条件判断中,None
被视为假值。None
并不是一个类,而是一个对象,它只是一个特殊的值,用于表示空值对象。
2、NoneType
:
NoneType
是 Python 中表示None
值的类型。它是一个真正的数据类型,用于表示None
对象的类型。None
是NoneType
类型的唯一实例对象。也就是说,None
是NoneType
类的一个实例。
None
是 Python 中表示空值的特殊常量,它属于 NoneType
类型。在 Python 中,NoneType
是一个单例类型,表示只有一个实例的类型,即 None
。当一个变量没有被赋予任何值时,它通常会被默认设置为 None
。
可以使用 type()
函数来检查变量的类型。例如:
x = None
print(type(x)) # 输出:<class 'NoneType'>
help("NoneType")
"""
No Python documentation found for 'NoneType'.
Use help() to get the interactive help utility.
Use help(str) for help on the str class.
"""
由于 None
是一个特殊的类型,它不能被视为其他任何类型的子类型。它是一个独立的类型,表示空值或空对象。在 Python 中,它经常用于表示空的、未知的或不存在的值。
所以,可以说 None
是 NoneType
类的实例对象。但是需要注意的是,None
并不是一个类本身,而是 NoneType
类的实例,用于表示空值。在 Python 中,None
和 NoneType
并不是可以自由创建的对象或类型,而是内置到语言中的特殊值和类型。
3、使用is判断None
在 Python 中,使用 is
操作符来判断变量是否为 None
是因为 is
操作符比 ==
操作符更准确地检查对象的身份标识。在 Python 中,每个对象都有一个唯一的身份标识,可以通过 id()
函数获取。
考虑以下示例:
a = None
b = None
# 使用 is 操作符判断身份标识
print(a is b) # 输出: True
# 使用 == 操作符判断值是否相等
print(a == b) # 输出: True
在上述例子中,a
和 b
都是 None
,因此它们的值相等。使用 ==
操作符可以检查两个对象的值是否相等,这对于检查 None
是有效的。然而,使用 is
操作符更常用,因为它不仅检查值是否相等,还检查对象的身份标识是否相同。
在 Python 中,None
是一个特殊的单例对象,表示空值或缺失值。因为 None
是单例对象,所以使用 is
操作符可以更精确地检查变量是否引用相同的 None
对象,而不仅仅是值是否相等。
总体来说,对于 None
的判断,推荐使用 is
操作符,除非你确切地知道你想要检查值是否相等而不关心对象的身份标识。
三、Python中的所有数据类型都是对象(实例对象),所有类都是数据类型,所有数据类型都是类
Python 中的所有数据都是对象,无论是基本数据类型还是引用数据类型。基本数据类型虽然是不可变的,但在进行操作时,可能会创建新的对象,这是因为 Python 中的对象都是按值传递的。而引用数据类型的内容可以在原对象上修改,因为这些对象在内存中是可变的。
四、判断数据类型运算符
变量名是没有数据类型的,只有变量值有数据类型,判断均为变量值的数据类型
1、type() -> object
内置类
type()
函数可以返回给定对象的类型。它可以用于判断变量、常量或表达式的数据类型。
例如:
x = 42
y = "Hello"
z = [1, 2, 3]
print(type(x)) # 输出:<class 'int'>
print(type(y)) # 输出:<class 'str'>
print(type(z)) # 输出:<class 'list'>
# 也可以使用type来判断类型
print(type(2) == int) # True
2、isinstance() ->bool
内置函数
isinstance()
函数用于检查一个对象是否属于指定的数据类型。它可以用于判断变量的类型是否为特定的类型或其子类。返回bool类型
例如:
x = 42
if isinstance(x, int):
print("x 是整数类型")
else:
print("x 不是整数类型")
isinstance()函数侧重于类,不是类型,因此不需要类型提前引用
class A(object):
def main(self) -> bool:
a: A = A()
return isinstance(a, A)
if __name__ == '__main__':
print(A().main()) #True
3、type()
和 isinstance()
的区别
type()
函数返回对象的精确类型,它会返回一个类的对象。isinstance()
函数可以检查对象是否为指定类型或其子类,它会返回布尔值 True 或 False。
在实际编程中,type()
和 isinstance()
经常用于检查函数参数的数据类型或进行条件判断,以确保正确处理不同类型的数据。根据具体需求,您可以选择合适的方式来判断数据的类型。
第五章、运算符重载和特殊方法
一、概述
类似于动作重载,虽然对象A和对象B有同样名称的动作,但是由于对象不同,动作的结果也就不同,这就是动作重载。
主要用于自定义对象和类的属性和行为。
运算符重载和特殊方法是Python面向对象编程中的重要概念,它们允许你自定义对象的行为,并使得你的类能够支持内置运算符和函数的操作。特殊方法是以双下划线开头和结尾的方法,它们在Python中有特殊的用途,用于实现运算符重载。
二、特殊方法
1、定义
特殊方法(也称为魔术方法或双下划线方法)是用于定义类在特定操作下的行为。这些特殊方法都有固定的命名格式,例如
__init__
、__add__
、__str__
等。它们在类的定义中具有特殊的含义,当对象执行相关操作时,Python 解释器会自动调用相应的特殊方法。
2、以实例方法为主
以实例方法为主,也有少部分静态方法(比如__new__)
3、作用理解
类似于接口,也可理解为接口方法,只要类中定义了这些特殊方法时,就表示该类的实例对象或者该类有对应特殊方法的功能(动作),Python会在适当的时候自动调用这些方法
这些方法在Python中有特殊的用途,当你在自定义类中定义了这些特殊方法时,Python会在适当的时候自动调用这些方法。这就是运算符重载的关键,你可以通过实现这些特殊方法来定制你的类对象在使用内置运算符时的行为。
像__abs__ 这样的方法都有什么作用,怎么调用,为什么这么奇怪
像__abs__
这样的方法是Python中的特殊方法(也称为魔术方法或双下划线方法)。它们是在对象中定义的特殊方法,用于实现特定的操作或行为。这些特殊方法的命名都以双下划线开始和结束,如__abs__
、__add__
、__sub__
等。
__abs__
方法是用于返回对象的绝对值的特殊方法。对于整数和浮点数来说,绝对值是该数的非负值。对于复数来说,绝对值是复数的模(magnitude,即复数到原点的距离)。
调用__abs__
方法的方式是使用内置函数abs()
,Python会自动调用对象的__abs__
方法来计算绝对值。
让我们看看如何调用__abs__
方法:
- 整数的绝对值:
num = -10
print(abs(num)) # 输出:10,调用了num对象的__abs__方法,返回绝对值10。
复数的绝对值:
complex_num = 3 + 4j
print(abs(complex_num)) # 输出:5.0,调用了complex_num对象的__abs__方法,返回复数的模5.0。
特殊方法之所以奇怪是因为它们的命名使用了双下划线,这样的命名使它们在Python中具有特殊的含义,而且这些方法会在特定的情况下被自动调用,而不需要显式地调用。这使得Python的对象模型非常灵活和强大,可以通过定义这些特殊方法来自定义对象的行为。例如,在自定义类中,你可以实现__abs__
方法来定义该类对象的绝对值计算方式。
也就是说对象有了__abs__这个方法的话,就表示该对象可以求绝对值了是吧
是的,你理解得很对!当一个对象定义了__abs__
方法,就表示该对象可以求绝对值。
在Python中,当你调用内置函数abs()
时,它会自动寻找对象的__abs__
方法,并调用该方法来计算对象的绝对值。因此,如果一个对象定义了__abs__
方法,那么它就具备了计算绝对值的能力。
这种通过特殊方法实现的机制称为"运算符重载",它允许用户自定义对象在使用内置运算符(如+
、-
、*
等)时的行为。对于绝对值的例子来说,如果你想自定义某个类的对象的绝对值计算方式,你只需要在该类中定义__abs__
方法,然后Python会在调用abs()
时自动调用该方法。
运算符重载和特殊方法是Python面向对象编程的重要概念,它使得你可以灵活地定义对象的行为和操作,增强了代码的灵活性和可读性。在使用特殊方法时,需要遵循Python的特殊方法命名约定,以确保这些方法能够在适当的时候被正确调用。
4、Python源码中特殊方法没有可见具体的实现代码
特殊方法之所以没有具体的实现源码,是因为它们是 Python 语言的内置功能。这些方法是在 Python 解释器中实现的,而不是作为普通的 Python 代码存在的。当对象执行特定操作时,Python 解释器会根据对象所属的类去查找对应的特殊方法,并在内部调用它们。因此,在类定义中通常使用 pass
占位符来表示特殊方法没有实际实现。这样可以使类定义更加简洁,而特殊方法的具体实现是由 Python 解释器来完成的。
5、自定义类中须重载实现特殊方法,才能达到效果
当我们在自定义类时,如果希望对象在特定操作下有特殊的行为,可以通过实现这些特殊方法来自定义类的行为。这样,在对象执行相应操作时,Python 解释器会调用我们定义的特殊方法,从而实现我们自定义的行为。
6、Python解释器自动调用特殊方法说明
通过符号调用
- 以__add__()方法为例:
- 实例对象a + 实例对象b ==》自动调用 实例对象a.__add__(实例对象b)
通过方法调用
- 以__round__()方法为例
- round(实例对象a, 实例对象b) ==》 自动调用 实例对象a.__round__(实例对象b)
- 以__abs__()方法为例
- abs(实例对象a) ==》 自动调用 实例对象a.__abs__()
二、运算符重载(动作重载)
运算符重载:运算符重载是指在自定义类中,通过实现特殊方法,使得类的对象可以支持内置运算符的操作。Python中的很多运算符,例如+
、-
、*
、/
、==
等,都可以通过特殊方法进行重载。通过重载运算符,你可以定义类对象在使用这些运算符时的行为。
1、动作重载原理
三、案例
假设我们要创建一个名为Vector
的类,用于表示二维向量。我们希望能够对向量进行加法和减法操作,并且能够比较两个向量是否相等。
首先,我们定义Vector
类并实现特殊方法:
class Vector:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
def __add__(self, other) -> "Vector":
if isinstance(other,Vector):
return Vector(self.x + other.x, self.y + other.y)
else:
raise
def __sub__(self, other) -> "Vector":
return Vector(self.x - other.x, self.y - other.y)
def __eq__(self, other) -> bool:
return self.x == other.x and self.y == other.y
现在我们可以创建Vector
对象,并进行运算符重载的操作:
# 创建两个向量
v1 = Vector(1, 2)
v2 = Vector(3, 4)
# 加法操作
result_add = v1 + v2
print(result_add.x, result_add.y) # 输出:4 6
# 减法操作
result_sub = v1 - v2
print(result_sub.x, result_sub.y) # 输出:-2 -2
# 相等比较
print(v1 == v2) # 输出:False
在上面的例子中,我们定义了Vector
类,并在其中实现了__add__
、__sub__
和__eq__
等特殊方法。通过这些特殊方法,我们可以实现向量的加法、减法和比较操作,使得Vector
对象可以支持内置运算符的操作。
总结:运算符重载和特殊方法允许你在自定义类中定义对象在使用内置运算符时的行为。通过实现特殊方法,你可以定制类对象的操作,使其具备更灵活和符合实际需求的行为。
第六章、int类型
Python中int类型就相当于java中的byte,short,int,long类型
一、概述
在Python中,
int
(整数)类型是用于表示整数数值的数据类型。int
类型是一种内置数据类型,可以用来表示正整数、负整数和零。
1、int类型所占的字节数为4字节或者8字节,默认值为0
在 Python 中,int 类型通常占据的字节数取决于操作系统和计算机架构。在大多数情况下,int 类型占据的字节数为4个字节(32位)或8个字节(64位)。
在 Python 3.x 版本中,int 类型的默认值为0。这意味着如果你创建一个整数类型的变量而没有为其赋值,它将默认为0。
例如:
print(int()) #0
2、int类型取值范围:取决于内存
在 Python 3.x 中,整数类型 int 可以表示任意大的整数,没有固定的最大值。它会根据需要自动转换为长整型(long)来存储超过机器字长的整数。
在 Python 2.x 版本中,整数类型分为 int 和 long 两种,int 类型的取值范围受限于机器字长,通常为32位或64位
在Python中,int
类型的整数没有固定的大小限制。它可以表示任意大的整数,取决于你的系统内存大小。Python会自动根据需要来分配内存,以便存储所需的整数。
总结:int
类型是Python中用于表示整数数值的内置数据类型。它没有固定的大小限制,可以表示任意大的整数。整数支持常见的运算和转换,是Python中非常常用和重要的数据类型。
3、整数运算
int
类型支持常见的整数运算,包括加法、减法、乘法和除法。在进行整数运算时,如果结果是整数,将返回int
类型的整数;如果结果是浮点数,将返回float
类型的浮点数。
4、不可变数据类型
Python的整数类型是一个封装了整数的类,这意味着整数是不可变的。每次对整数进行运算时,都会创建一个新的整数对象,而不会修改原始整数对象。这也使得整数在多线程环境中是线程安全的。
二、整数的表示(默认为十进制)
1、十进制
整数在Python中以十进制的形式表示,默认情况下没有前导零。例如,42
和-100
都是int
类型的整数。
2、十六进制
十六进制数以
0x
或0X
开头
3、八进制
八进制数以
0o
或0O
开头
4、二进制
二进制数以
0b
或0B
开头
#默认为十进制
print(10) #10
#十六进制
print(0x10) #16
#八进制
print(0o10) #8
#二进制
print(0b10) #2
三、int类型是封装了整数的类(class int)
在Python中,虽然我们将整数看作基本数据类型,但实际上,Python中的整数是封装在一个类中的对象。这个类称为
int
类,它是Python内置的一个类。这意味着在Python中创建一个整数时,实际上是创建了一个int
类的实例。
要理解整数是封装了整数的类,可以考虑以下例子:
# 创建一个整数对象
x = 42
# 检查x的类型
print(type(x)) # 输出:<class 'int'>
在这个例子中,我们创建了一个整数x
,然后使用type()
函数检查x
的类型。输出结果显示x
的类型是<class 'int'>
,表示x
是int
类的一个实例。
因为整数是类的实例,所以整数具有类的特性和方法。例如,我们可以使用dir()
函数来查看整数对象的属性和方法:
print(dir(x))
输出结果将包含一系列整数对象可以调用的方法和属性。这些方法和属性允许我们在整数上进行各种操作,例如进行算术运算、位运算等。
这种将整数封装在类中的设计是Python中的一种对象导向的编程(Object-Oriented Programming,简称OOP)的概念。Python中的很多数据类型实际上都是类的实例,包括整数、浮点数、字符串、列表等。这使得Python非常灵活和强大,可以通过调用类的方法来操作不同类型的数据。
总结:在Python中,整数是封装在int
类中的对象。虽然我们将其视为基本数据类型,但实际上它是int
类的实例,具有类的特性和方法。这种设计使得整数具有更多的灵活性,并让Python支持面向对象的编程范式。
四、常用方法
在Python中,int
类型是整数的数据类型。除了基本的算术运算外,int
类型还提供了一些常用的方法来对整数进行操作和转换。下面是一些常用的int
类型方法:
1、bit_length()
: 返回整数的二进制表示的位数(不包括符号位)
例如,
5
的二进制表示为101
,因此5.bit_length()
返回3
。
num = 42
print(num.bit_length()) # 输出:6(42的二进制表示是'101010',有6位)
2、to_bytes(length, byteorder, signed)
: 将整数转换为字节序列。
length
指定期望的字节数,byteorder
指定字节序('big'表示大端序,'little'表示小端序),signed
指定是否要包含符号位。
num = 2021
bytes_representation = num.to_bytes(2, byteorder='big')
print(bytes_representation) # 输出:b'\x07\xe5'(2021的大端序字节表示)
3、from_bytes(bytes, byteorder, signed)
: 将字节序列转换为整数
bytes
是要转换的字节序列,byteorder
指定字节序,signed
指定是否包含符号位。
bytes_representation = b'\x07\xe5'
num = int.from_bytes(bytes_representation, byteorder='big')
print(num) # 输出:2021(将大端序字节转换回整数2021)
4、conjugate()
、real
和 imag
方法
conjugate()
: 返回整数的共轭复数。对于实数,共轭复数等于自身。
real
: 返回整数的实部,与整数本身相同。
imag
: 返回整数的虚部,对于实数,虚部为0。
complex_num = 2 + 3j
print(complex_num.conjugate()) # 输出:(2-3j)(复数2 + 3j 的共轭为 2 - 3j)
print(complex_num.real) # 输出:2(复数的实部)
print(complex_num.imag) # 输出:3(复数的虚部)
5、__abs__()
: 返回整数的绝对值(abs() 调用)
num = -10
print(abs(num)) # 输出:10(-10 的绝对值是 10)
6、__add__(other)
: 实现整数与其他对象的加法操作(+ 调用)
这个特殊方法用于实现整数对象与其他对象的加法操作(
+
运算符)。当整数对象使用
+
运算符与其他对象相加时,Python 会调用__add__
方法来实现加法运算。
class MyInt:
def __init__(self, value:int):
self.value = value
#MyInt类型提示前向引用,需要加引号
def __add__(self, other:Any) -> "MyInt":
if isinstance(other, MyInt):
return MyInt(self.value + other.value)
else:
raise
num1 = MyInt(5)
num2 = MyInt(10)
#使用+运算符时,会自动调用__add__方法
result = num1 + num2
print(result.value) # Output: 15
7、__sub__(other)
: 实现整数与其他对象的减法操作(- 调用)
这个特殊方法用于实现整数对象与其他对象的减法操作(
-
运算符)。当整数对象使用
-
运算符与其他对象相减时,Python 会调用__sub__
方法来实现减法运算。
class MyIntSub(object):
#重写父类object的方法
def __init__(self,value:int):
self.value = value
def __sub__(self, other: "MyIntSub") -> "MyIntSub":
if isinstance(other,MyIntSub):
return MyIntSub(self.value - other.value)
else:
raise
a:MyIntSub = MyIntSub(10)
b:MyIntSub = MyIntSub(5)
#使用 - 运算符时,会自动调用__sub__方法
result:MyIntSub = a - b
print(result.value) #输出5
8、__mul__(other)
: 实现整数与其他对象的乘法操作(* 调用)
这个特殊方法用于实现整数对象与其他对象的乘法操作(
*
运算符)。当整数对象使用
*
运算符与其他对象相乘时,Python 会调用__mul__
方法来实现乘法运算。
class MyIntMul(object):
#构造方法
def __init__(self,value:int) -> None:
self.value = value
def __mul__(self, other:"MyIntMul") -> "MyIntMul":
if isinstance(other,MyIntMul):
return MyIntMul(self.value * other.value)
else:
raise
a:MyIntMul = MyIntMul(10)
b:MyIntMul = MyIntMul(3)
#使用乘法 * 时会自动调用 __mul__方法
result:MyIntMul = a * b
print(result.value) #30
9、__floordiv__(other)
: 实现整数与其他对象的整数除法操作(取整操作 //调用)
这个特殊方法用于实现整数对象与其他对象的整数除法操作(
//
运算符)。当整数对象使用
//
运算符与其他对象进行整数除法时,Python 会调用__floordiv__
方法来实现整数除法。
class MyIntFloordiv(object):
#构造方法
def __init__(self,value:int) -> None:
self.value = value
def __floordiv__(self, other: "MyIntFloordiv") -> "MyIntFloordiv":
if isinstance(other,MyIntFloordiv):
return MyIntFloordiv(self.value // other.value)
else:
raise
a: MyIntFloordiv = MyIntFloordiv(10)
b: MyIntFloordiv = MyIntFloordiv(3)
#当使用//运算符时,会自动调用__floordiv__方法
result: MyIntFloordiv = a // b
print(result.value)
10、__truediv__(other)
: 实现整数与其他对象的真除法操作(保留小数除法 / 调用)。
这个特殊方法用于实现整数对象与其他对象的真除法操作(
/
运算符)。当整数对象使用
/
运算符与其他对象进行真除法时,Python 会调用__truediv__
方法来实现真除法。
class MyIntTruediv(object):
#构造方法
def __init__(self,value):
self.value = value
def __truediv__(self, other:"MyIntTruediv") -> "MyIntTruediv":
if isinstance(other,MyIntTruediv):
return MyIntTruediv(self.value / other.value)
else:
raise
a:MyIntTruediv = MyIntTruediv(10)
b:MyIntTruediv = MyIntTruediv(3)
#当使用/运算符时,会自动调用__truediv__方法
result:MyIntTruediv = a / b
print(result.value) #3.3333333333333335
11、__mod__(other)
: 实现整数与其他对象的取模操作(取余数操作 % 调用)
这个特殊方法用于实现整数对象与其他对象的取模操作(
%
运算符)。当整数对象使用
%
运算符与其他对象进行取模运算时,Python 会调用__mod__
方法来实现取模运算。
class MyIntMod(object):
#构造方法
def __init__(self,value:int) -> None:
self.value = value
def __mod__(self, other:"MyIntMod") -> "MyIntMod":
if isinstance(other,MyIntMod):
return MyIntMod(self.value % other.value)
else:
raise
# pass
a:MyIntMod = MyIntMod(10)
b:MyIntMod = MyIntMod(3)
#当使用%运算符时,会自动调用__mod__方法
result:MyIntMod = a % b
print(result.value) #1
12、__pow__(other, modulus)
: 实现整数的幂运算(** 调用)
参数modulus
可选,指定计算幂时的模数。
这个特殊方法用于实现整数对象的幂运算(
**
运算符)。第一个参数
other
表示幂运算的指数,第二个参数modulus
(可选)表示幂运算时的模数。当整数对象使用
**
运算符进行幂运算时,Python 会调用__pow__
方法来实现幂运算。
class MyIntPow(object):
#构造方法
def __init__(self,value:...) -> None:
self.value = value
def __pow__(self, power:"MyIntPow", modulo=None) ->"MyIntPow":
if isinstance(power,MyIntPow):
return MyIntPow(self.value ** power.value)
else:
raise
a:MyIntPow = MyIntPow(2)
b:MyIntPow = MyIntPow(3)
#当使用**运算符时,会自动调用__pow__方法
result:MyIntPow = a ** b
print(result.value) #8
13、__round__( ndigits: SupportsIndex = ...) -> int 用于执行浮点数的四舍五入操作,并返回最接近的整数(round方法调用)
round(number[, ndigits])
参数说明:
number
:表示要进行四舍五入的数字。ndigits
(可选):表示要保留的小数位数,默认为 0。如果省略ndigits
参数,则round()
函数会将number
四舍五入到最接近的整数。
round()
函数的工作原理如下:
- 如果
ndigits
参数为正数,则number
会四舍五入到小数点后的第ndigits
位。例如,round(3.14159, 2)
返回 3.14,保留两位小数。 - 如果
ndigits
参数为负数,则number
会四舍五入到整数的个位、十位等位置上。例如,round(12345, -2)
返回 12300,保留到最近的百位。
使用示例:
result1 = round(3.14159) # 不指定 ndigits,默认四舍五入到整数
print(result1) # 输出:3
result2 = round(3.14159, 2) # 四舍五入到小数点后两位
print(result2) # 输出:3.14
result3 = round(12345, -2) # 四舍五入到最近的百位
print(result3) # 输出:12300
round()
函数在处理浮点数时要注意其可能引发的精度问题,因为在某些情况下,浮点数的存储和运算可能会导致一些不精确的结果。如果需要高精度的数学计算,可以考虑使用 Python 的decimal
模块来进行精确计算。
这些是int
类型的一些常用方法,可以帮助你对整数进行各种操作和转换。需要注意的是,int
类型是不可变类型,因此这些方法并不会修改原始的整数对象,而是返回一个新的结果。
14、__divmod__(self, x: int) -> tuple[int, int] 返回一个元组,其中包含除法的商和取模的结果
语法:
def __divmod__(self, other):
"""
Return the tuple (x // y, x % y).
"""
pass
其中,self
表示当前的整数对象,other
表示除数。
使用示例:
x = 10
y = 3
quotient, remainder = divmod(x, y)
print(quotient) # 输出:3,表示整数除法的结果
print(remainder) # 输出:1,表示取模的结果
print(divmod(10,3)) #(3, 1)
在上面的示例中,我们使用了 Python 内置函数 divmod()
来执行整数除法和取模操作,并将结果分别赋值给 quotient
和 remainder
变量。
实际上,divmod(x, y)
等价于 x.__divmod__(y)
,也就是调用 x
这个整数对象的 __divmod__
方法。该方法会返回整数除法的商和取模的结果,以一个元组的形式返回。
__divmod__
方法在整数对象中的实现是由 Python 解释器完成的,通常不需要我们手动定义。它是一种特殊方法,用于支持内置函数 divmod()
和其他相关操作。
五、int类型转换
Python提供了各种函数来在不同进制和数据类型之间进行整数转换。例如,int()
函数用于将其他类型的数据转换为整数,bin()
、oct()
和hex()
函数用于将整数转换为二进制、八进制和十六进制字符串。
1、int(x)
@overload
def __new__(cls: Type[_T], x: str | bytes | SupportsInt | SupportsIndex | _SupportsTrunc = ...) -> _T: ...
2、int(x, base=10)
@overload
def __new__(cls: Type[_T], x: str | bytes | bytearray, base: SupportsIndex) -> _T: ...
x
:待转换的参数,可以是字符串、浮点数、布尔值或其他支持转换为整数的类型。base
(可选参数):表示待转换的进制,默认为10,可选的进制参数base
可以用于指定字符串的进制,例如:
- base = 16 表示解析16进制字符串转换为10进制整数
- base = 8 表示解析8进制字符串转换为10进制整数
- base = 2 表示解析2进制字符串转换为10进制整数
2.1、int()函数将其他数据类型转换为int类型原理
int(x)其实是int类的对象,当调用int(x)函数时,先调用int类的__new__方法创建实例对象,然后该实例对象调用__init__()构造方法来初始化该实例对象,在这过程中会调用x对象的__int__方法将x对象的类型转换为int类型(若x对象中没有__int__方法,则无法转换,str除外)
2.2、__int__方法解析
在 Python 中,__int__()
是一个特殊方法(也称为魔术方法),用于自定义类的实例对象在转换为整数时的行为。当我们将一个对象转换为整数时,Python 解释器会自动调用该对象的 __int__()
方法,从而实现对象到整数的转换。
__int__()
方法的语法如下:
class MyClass:
def __int__(self):
"""
Custom implementation for converting the object to an integer.
"""
pass
在上面的示例中,MyClass
是一个自定义类,其中定义了 __int__()
方法。我们可以在这个方法中自定义对象到整数的转换逻辑。
使用示例:
class MyInt:
def __init__(self, value):
self.value = value
def __int__(self):
return self.value
num = MyInt(42)
result = int(num)
print(result) # 输出:42
在上面的示例中,我们定义了一个名为 MyInt
的类,其中包含 __init__()
和 __int__()
方法。__init__()
用于初始化对象的值,__int__()
则返回对象的整数值。当我们调用内置函数 int()
来将 MyInt
类的对象转换为整数时,Python 解释器会自动调用 __int__()
方法,从而获取对象的整数值并返回。
需要注意的是,__int__()
方法应该返回一个整数类型的值,否则会引发 TypeError。这个方法的主要用途是在自定义类的实例在转换为整数时提供一个合适的行为。
2.3、int()函数可转换的数据类型
-
浮点数:
int()
将截断浮点数的小数部分,返回整数部分。例如,int(3.14)
将返回3
。 -
布尔值:
True
会转换为整数1
,False
会转换为整数0
。 -
字符串(具有数字的字符串):
int()
会尝试将字符串解析为整数。如果字符串不符合整数格式,将会抛出ValueError
异常。可选的进制参数base
可以用于指定字符串的进制,例如base=16
表示解析16进制字符串。
str
类中并没有__int__
方法。实际上,Python中可以将字符串转换为整数是因为int()
函数使用了字符串解析的方式来进行转换,而不是通过__int__
方法。
int()
函数会尝试解析给定的字符串,将其转换为整数。它会逐个字符地检查字符串,并按照整数的格式解析。例如,对于字符串"123"
,int()
函数会将字符'1'
解析为1,字符'2'
解析为2,字符'3'
解析为3,然后将它们组合成整数123
。然而,如果字符串无法被正确解析为整数,
int()
函数会引发ValueError
异常。例如,对于字符串"hello"
,它并不符合整数格式,因此会引发异常。在解析过程中,
int()
函数还支持指定进制(即基数)。例如,int("1A", base=16)
会将字符串"1A"
解析为16进制数,最终返回整数26
。
# 将字符串转换为整数
num_str = "123"
num_int = int(num_str)
print(num_int) # 输出: 123
# 指定进制进行转换
hex_str = "1A"
hex_int = int(hex_str, base=16)
print(hex_int) # 输出: 26
# 转换浮点数(小数部分将被截断)
float_num = 3.14
int_num = int(float_num)
print(int_num) # 输出: 3
# 转换布尔值
bool_val = True
int_val = int(bool_val)
print(int_val) # 输出: 1
请注意,在使用int()
函数时,始终确保提供的参数是合法且可转换为整数,以避免出现异常。
3、将整数转换为对应的二进制、八进制和十六进制字符串表示形式
Python中bin()、oct()和hex()这样的方法为什么没有像__bin__这样的特殊方法
在 Python 中,bin()
、oct()
和 hex()
是内置函数,而不是特殊方法(魔术方法)。它们用于将整数转换为对应的二进制、八进制和十六进制字符串表示形式。这些函数是 Python 语言提供的便捷工具,用于进行整数与进制字符串之间的转换,而不是用于在类中定义对象的行为。
与特殊方法(例如 __str__
、__add__
等)不同,这些内置函数并不是用于在类的定义中实现自定义行为的。它们是 Python 内置的功能,设计用于特定用途的实用函数,如整数进制转换、格式化输出等。
例如,bin()
函数用于将整数转换为二进制字符串:
x = 10
binary_string = bin(x)
print(binary_string) # 输出:'0b1010'
这里我们并没有在类的定义中使用 __bin__
这样的特殊方法,而是直接使用了内置函数 bin()
来完成整数转换的操作。
特殊方法(魔术方法)主要用于自定义类的行为和操作,例如重载加法运算、字符串表示等。这些方法在类的定义中以特殊的双下划线命名,用于在对象执行特定操作时由 Python 解释器自动调用。而 bin()
、oct()
和 hex()
等函数是 Python 内置函数库提供的标准功能,是由解释器在内部实现的。因此,它们并不需要像特殊方法那样在类的定义中实现。
1、bin()
函数
- 用于将整数转换为二进制字符串。
- 语法:
bin(x)
- 参数
x
是一个整数,返回一个以'0b'
开头的二进制字符串,其中'0b'
表示二进制数的前缀。 - 示例:
x = 10
binary_string = bin(x)
print(binary_string) # 输出:'0b1010'
2、oct()
函数
- 用于将整数转换为八进制字符串。
- 语法:
oct(x)
- 参数
x
是一个整数,返回一个以'0o'
开头的八进制字符串,其中'0o'
表示八进制数的前缀。 - 示例:
x = 10
octal_string = oct(x)
print(octal_string) # 输出:'0o12'
3、hex()
函数:
- 用于将整数转换为十六进制字符串。
- 语法:
hex(x)
- 参数
x
是一个整数,返回一个以'0x'
开头的十六进制字符串,其中'0x'
表示十六进制数的前缀。 - 示例:
x = 10
hexadecimal_string = hex(x)
print(hexadecimal_string) # 输出:'0xa'
这些函数通常用于整数的进制转换和格式化输出。需要注意的是,这些函数返回的结果都是字符串类型。如果需要将二进制、八进制或十六进制字符串转换回整数,可以使用 int()
函数,并指定相应的进制基数参数。例如:
binary_string = '0b1010'
x = int(binary_string, 2) # 将二进制字符串转换为整数
print(x) # 输出:10
第七章、float类型
一、概述
Python中的float类型相当于java中的float,double类型
在 Python 中,float
类型是一种浮点数类型,用于表示实数(包括小数和整数)。浮点数是一种近似表示的数值类型,可以表示非常大或非常小的数,以及包含小数部分的数值。浮点数在计算机中用于处理需要更高精度的数学计算和科学计算等场景。
1、float类型所占的字节数为8字节,默认值为0
在 Python 中,
float
类型占据 8 个字节(64 位),它采用 IEEE 754 双精度浮点数表示格式。这使得float
类型在表示实数时能够提供较高的精度,并能够表示非常大或非常小的数值。
float
类型的默认值为 0.0。在创建一个没有明确赋值的float
类型变量时,默认会被初始化为 0.0。
以下是一个示例:
# 浮点数类型占据8个字节(64位)
x = 1.23
y = 3.14
print(x) # 输出:1.23
print(y) # 输出:3.14
# 浮点数类型默认值为0.0
z = float()
print(z) # 输出:0.0
在上面的示例中,我们定义了两个浮点数变量 x
和 y
,它们分别赋值为 1.23 和 3.14。我们还定义了一个没有明确赋值的浮点数变量 z
,它的默认值为 0.0。
2、float类型取值范围
在 Python 中,
float
类型采用 IEEE 754 双精度浮点数表示格式,可以表示的浮点数范围约为 ±1.7976931348623157e308 。
在 Python 中,超出浮点数范围的数值将被表示为正或负的无穷大(inf
或 -inf
),或者被表示为特殊的非数值(NaN,表示"not a number")。例如:
# 表示正无穷大
positive_inf = float("inf")
print(positive_inf) #inf
# 表示负无穷大
negative_inf = float('-inf')
print(negative_inf) #-inf
# 表示非数值
nan = float("nan")
print(nan) #nan
需要注意的是,浮点数类型的精度有限,所以在进行浮点数计算时可能会产生舍入误差。对于需要高精度计算的场景,可以使用 Python 中的
decimal
模块来进行高精度的浮点数计算。
以下是一个示例,展示浮点数的取值范围和一些特殊的浮点数表示:
# 浮点数的取值范围
min_float = -1.7976931348623157e308
max_float = 1.7976931348623157e308
print(min_float) # 输出:-1.7976931348623157e+308
print(max_float) # 输出:1.7976931348623157e+308
# 特殊的浮点数表示
print(float('inf')) # 输出:inf
print(float('-inf')) # 输出:-inf
print(float('nan')) # 输出:nan
3、浮点数运算
浮点数可以进行数学运算,包括加减乘除等操作:
num1 = 2.5
num2 = 1.3
result = num1 + num2
print(result) # 输出: 3.8
result = num1 * num2
print(result) # 输出: 3.25
4、精度问题
浮点数的有限精度可能导致一些精度问题,例如:
num1 = 0.1
num2 = 0.2
result = num1 + num2
print(result) # 输出: 0.30000000000000004
这是由于0.1和0.2在二进制浮点数中无法精确表示,导致了微小的舍入误差。
如果您需要高精度的数值计算,可以使用decimal
模块中的Decimal
类型,它提供更高的精度,并避免了浮点数的舍入误差。
5、不可变数据类型
float
类型是Python中的不可变数据类型,不可变数据类型是指一旦创建后,其值不能被修改,如果对其进行操作或修改,会生成一个新的对象。float
类型属于不可变数据类型,这意味着一旦创建了一个浮点数对象,就无法直接修改其值。
让我们通过一些例子来说明不可变数据类型的特点:
# 创建一个浮点数对象
num_float = 3.14
# 尝试修改浮点数的值,会生成一个新的对象
num_float = 2.71
# 上面的操作不是直接修改原始对象,而是创建了一个新的浮点数对象
二、浮点数的表示:只能以十进制表示
float
类型在Python中用于表示浮点数,它是一种有限精度的数据类型。浮点数采用二进制浮点数表示方式,通常遵循IEEE 754标准。
浮点数的表示并不直接使用二进制、八进制或十六进制的形式,而是采用一种叫做"双精度浮点数"的格式。这种格式使用二进制科学计数法(二进制指数和尾数),将浮点数表示为一个符号位、指数位和尾数位的组合。
这种表示方式使得浮点数可以在广泛的数值范围内表示非常大和非常小的数值,但也导致了一些精度问题。由于浮点数的有限精度,有些数值无法在二进制浮点数中精确表示,这会引起舍入误差。
这就是为什么在进行浮点数计算时,特别是涉及到比较运算时,可能会出现一些意外的结果。为了避免这种情况,在需要高精度计算时,可以使用decimal
模块中的Decimal
类型,它提供更高的精度。
总结一下,
float
类型在Python中表示浮点数,并使用IEEE 754标准的双精度浮点数格式进行内部存储,而不是直接以二进制、八进制或十六进制的形式表示
当我们写一个浮点数时,它默认为十进制数。例如:
decimal_float = 3.14
print(decimal_float) # 输出: 3.14
如果您有一个十六进制数,并希望将其转换为浮点数,您需要先将其转换为十进制数,然后再创建一个float
类型的对象。
hex_string = "0x1A"
decimal_number = int(hex_string, 16)
float_number = float(decimal_number)
print(float_number) # 输出: 26.0
在这里,我们首先使用int()
将十六进制字符串"0x1A"
转换为十进制整数26
,然后使用float()
将整数26
转换为浮点数26.0
。
三、float类型是封装了浮点数的类(class float)
在Python中,float
是表示浮点数的内置数据类型,也是一个内置类。它用于存储带有小数部分的浮点数值,并在计算机内部以IEEE 754标准的双精度浮点数格式进行表示。
浮点数由一个符号位、指数位和尾数位组成,可以表示非常大和非常小的数值。然而,由于浮点数的有限精度,它可能无法精确表示一些数值,可能会引起舍入误差。
在Python中,您可以使用float()
构造函数或直接赋值来创建浮点数对象。以下是一些示例:
# 使用 float() 构造函数创建浮点数对象
num_float = float(3.14)
print(num_float) # 输出: 3.14
# 直接赋值创建浮点数对象
# 自动装箱机制
pi = 3.14159
print(pi) # 输出: 3.14159
#float类型创建实例对象及初始化过程
a = float.__new__(float,123)
a.__init__()
print(a) #123.0
四、float类型的科学计数法
在Python中,float
类型的科学表示法指的是浮点数的科学计数法(scientific notation)。科学计数法用于表示非常大或非常小的数值,并且可以简洁地表示这些数值。
科学计数法的表示形式如下:
a x 10^b
其中,a
是一个介于 1.0(包含)与 10.0(不包含)之间的数,称为尾数或有效数字(significand),b
是一个整数,表示指数。
在浮点数的科学计数法中,尾数可以是整数或小数,指数可以是正整数或负整数。指数为正数时表示非常大的数,指数为负数时表示非常小的数。
Python中的浮点数可以用科学计数法来表示。以下是一些示例:
# 1.0 x 10^3 = 1000.0
num1 = 1e3
print(num1) # 输出: 1000.0
# 3.14 x 10^-2 = 0.0314
num2 = 3.14e-2
print(num2) # 输出: 0.0314
在这些示例中,1e3
表示 1.0 乘以 10 的 3 次方,即 1000.0。而 3.14e-2
表示 3.14 乘以 10 的负 2 次方,即 0.0314。
使用科学计数法,可以更清晰地表示非常大或非常小的数值,有助于简化数据的表示和处理。
五、常用方法
1、as_integer_ratio()
: 将浮点数表示为分数的形式,返回一个元组 (numerator, denominator)
num_float = 3.14
ratio = num_float.as_integer_ratio()
print(ratio) # 输出: (7070651414971679, 2251799813685248)
2、is_integer()
: 检查浮点数是否表示一个整数
num_float = 3.0
result = num_float.is_integer()
print(result) # 输出: True
num_float = 3.14
result = num_float.is_integer()
print(result) # 输出: False
3、hex()
: 将浮点数表示为十六进制字符串
num_float = 3.14
hex_string = num_float.hex()
print(hex_string) # 输出: '0x1.91eb851eb851fp+1'
六、float类型转换
在 Python 中,float 类型的转换主要是将其他数据类型转换为 float 类型或者将 float 类型转换为其他数据类型。常见的 float 类型转换包括以下几种:
1、将int类型转换为float类型
# 从整数转换为 float
num_int = 10
float_num = float(num_int)
print(float_num) #10.0
2、将字符串(具有数字的字符串)转换为float类型
# 从字符串转换为 float
num_str = "3.14"
float_num = float(num_str)
print(float_num) #3.14
3、将布尔类型转换为 float 类型(True 转换为 1.0,False 转换为 0.0)
bool_value = True
float_value = float(bool_value) # 结果为 1.0
bool_value = False
float_value = float(bool_value) # 结果为 0.0
4、将其他类型转换为 float 类型时需要注意可能引发异常的情况
# 转换非法字符串为 float,会引发 ValueError
num_str = "hello"
try:
float_num = float(num_str)
except ValueError as e:
print("Error:", e) #Error: could not convert string to float: 'hello'
需要注意的是,使用 float() 函数进行转换时,如果转换失败(例如字符串中包含非法字符),将会引发 ValueError 异常,因此在进行 float 类型转换时最好使用 try-except 块来处理异常情况。
七、int和float类型之间互相转换
1、自动类型转换
小容量向大容量转换
任何浮点型逐渐不管占多少字节,都比整数型容量大
# int 自动转换为 float
x = 10
y = 3.14
result = x + y
print(result) # 输出 13.14
2、强制类型转换
大容量转换成小容量
# float 不会自动转换为 int
a = 5.7
b = 3
result2 = a + b
print(result2) # 输出 8.7,结果为 float 类型
c = int(a) + b
print(c) # 输出 8,结果为 int 类型,使用 int() 函数显式进行转换
总结:Python 中 int 类型可以隐式转换为 float 类型,但是 float 类型不能隐式转换为 int 类型。如果需要将 float 类型转换为 int 类型,可以使用 int()
函数进行显式转换。
3、多种数据做混合运算,先转换成容量最大的那种类型再做运算,最终结果也为容量最大的那种类型
在 Python 中,int 类型可以自动转换为 float 类型,但 float 类型不能自动转换为 int 类型。
当进行混合类型运算时,Python 会根据运算符的优先级和操作数的类型进行隐式类型转换。如果参与运算的操作数中包含 float 类型,那么整个运算结果会被转换为 float 类型。这意味着 int 类型会自动转换为 float 类型,但反过来 float 类型不会自动转换为 int 类型。
第八章、bool类型
一、概述
1、bool类型所占字节数为1字节,默认值为False
在 Python 中,bool 类型占用的字节数是 1 字节。bool 类型表示布尔值,只有两个取值:True 和 False。
默认情况下,bool 类型的默认值是 False。这意味着在创建一个新的 bool 类型变量时,如果没有明确赋值为 True,则它将自动被设置为 False。例如:
# 默认情况下,b1 被设置为 False
b1 = bool()
print(b1) # 输出 False
# 显式赋值为 True
b2 = True
print(b2) # 输出 True
2、bool类型只有True和False两个值,支持隐式类型转换
在 Python 中,bool 类型只有两个取值,分别是 True 和 False。
- True: 表示真值,用于表示逻辑上为真的情况。
- False: 表示假值,用于表示逻辑上为假的情况。
这两个取值在条件判断和逻辑运算中起着重要的作用,例如在 if 语句中,条件为 True 时执行相应的代码块,条件为 False 时则跳过代码块。在逻辑运算中,True 和 False 可以进行与、或、非等运算。
以下是一些使用 bool 类型取值的示例:
# 条件判断示例
x = 10
y = 20
if x < y:
print("x is less than y") # 输出 x is less than y
# 逻辑运算示例
a = True
b = False
print(a and b) # 输出 False
print(a or b) # 输出 True
print(not a) # 输出 False
隐式类型转换:Python 中的一些类型在进行 bool 类型转换时,会被隐式地转换为 True 或 False。
以下类型的值会被转换为 False:
- 数字类型:0 (包括整数、浮点数、复数等)。
- 布尔类型:False。
- 字符串类型:空字符串 ""。
- 序列类型:空列表 []、空元组 ()、空集合 set()。
- 映射类型:空字典 {}。
- None 类型:None。
其他非空、非零的值都会被隐式转换为 True。
# 隐式类型转换
print(bool(0)) # 输出 False
print(bool(10)) # 输出 True
print(bool("")) # 输出 False
print(bool("Hello")) # 输出 True
print(bool([])) # 输出 False
print(bool([1, 2, 3])) # 输出 True
print(bool({})) # 输出 False
print(bool({"a": 1})) # 输出 True
print(bool(None)) # 输出 False
3、真值测试:__bool__()方法
真值测试:在条件判断和逻辑运算中,Python 会对值进行真值测试。除了上述隐式类型转换规则外,还有一些对象的特殊方法(如 __bool__()
、__len__()
等)可以自定义对象的真值测试行为。
# 真值测试
class MyClass:
def __bool__(self):
return False
obj = MyClass()
print(bool(obj)) # 输出 False
4、bool类型运算
在 Python 中,bool 类型可以进行运算,也可以参与逻辑运算和比较运算。
运算:bool 类型在运算时会被隐式转换为整数类型。True 被转换为 1,False 被转换为 0。这样,我们可以对 bool 类型的变量进行数值运算,例如加法、减法、乘法等。当进行数值运算时,True 视为 1,False 视为 0。
print(True + True) # 输出 2
print(True - False) # 输出 1
print(True * 10) # 输出 10
print(False * 5) # 输出 0
逻辑运算:bool 类型可以参与逻辑运算,包括与(and)、或(or)、非(not)等运算。
print(True and False) # 输出 False
print(True or False) # 输出 True
print(not True) # 输出 False
比较运算:bool 类型也可以参与比较运算,例如与数值类型的比较。
print(True == 1) # 输出 True
print(False != 0) # 输出 False
需要注意的是,虽然 bool 类型可以进行运算,但在实际应用中,通常我们更多地使用 bool 类型进行条件判断和逻辑判断,而较少将其用于数值运算。数值运算主要针对数值类型,而不是 bool 类型。
5、不可变数据类型
bool 类型在 Python 中属于不可变数据类型。不可变数据类型是指一旦创建后,其值就不能再被修改。对于 bool 类型,只有两个取值,True 和 False,一旦创建了一个 bool 类型的变量,其值就固定为 True 或 False,无法改变。
x = True
y = False
x = False # 这里实际上是创建了一个新的 bool 对象,并将 x 的引用指向了该对象
在上面的例子中,当执行 x = False
时,实际上是创建了一个新的 bool 对象,并将 x 的引用指向了该对象,原来的 True 对象并没有被修改,而是被丢弃了。
因为 bool 类型是不可变的,所以在进行逻辑运算或条件判断时,我们可以放心地使用 bool 类型的值,因为它们不会被意外地改变。
二、bool类型是封装了的类(class bool(int))
在 Python 中,bool 类型是一个内置的数据类型,它是一个封装了的类,继承自 int 类型。实际上,bool 类型只有两个值,True 和 False,分别对应整数值 1 和 0。
因为 bool 类型是继承自 int 类型的,所以它继承了 int 类型的一些特性和方法。例如,我们可以将 True 和 False 当作整数来使用,进行加减乘除等运算。True 的整数值是 1,False 的整数值是 0。
三、bool表达式(底层调用__bool__方法)
布尔类型常用于表示条件表达式的结果。例如,比较运算符(如 ==、!=、<、>、<=、>=)的结果将产生布尔值。
# 布尔表达式示例
x = 10
y = 5
is_greater = x > y # 结果为 True
四、 bool类型用于条件语句
在条件语句中(如 if-else),布尔类型用于判断条件的真假,从而决定程序的执行路径。
# 条件语句示例
num = 7
if num % 2 == 0:
print("偶数")
else:
print("奇数")
五、bool类型用于循环
布尔值可以用于控制循环的执行。例如,在 while 循环或 for 循环中,可以用布尔类型来判断是否继续循环。
# 布尔值用于循环示例
is_running = True
count = 0
while is_running:
count += 1
if count == 10:
is_running = False
print("循环结束")
六、常用方法
在 Python 中,bool 类型并没有自己独有的方法,因为它是 int 类型的子类,继承了 int 类型的所有方法。实际上,bool 类型的对象可以当作整数来使用,所以可以使用 int 类型的方法对 bool 类型的对象进行操作。
以下是一些常用的 int 类型方法,在 bool 类型上同样适用:
-
__bool__()
方法:用于返回 bool 类型对象的布尔值 True 或 False。通常在条件判断中使用。 -
__eq__(other)
方法:用于判断两个 bool 类型对象是否相等。 -
__ne__(other)
方法:用于判断两个 bool 类型对象是否不相等。 -
__int__()
方法:将 bool 类型对象转换为整数值 1 或 0。 -
__str__()
方法:返回 bool 类型对象的字符串表示,即 'True' 或 'False'。
示例:
x = True
y = False
# 使用 bool 类型对象进行条件判断
if x:
print("x is True")
else:
print("x is False")
# 使用 int 类型的方法对 bool 类型对象进行操作
z = int(x)
print(z) # 输出:1
# 判断两个 bool 类型对象是否相等
print(x == y) # 输出:False
# 将 bool 类型对象转换为字符串
print(str(x)) # 输出:'True'
需要注意的是,bool 类型是不可变类型,一旦创建后,其值不能被修改。因此,在实际使用中,我们通常不会对 bool 类型对象调用任何修改值的方法。
七、bool类型转换(bool()函数,显示类型转换)
以下类型的值会被转换为 False:
- 数字类型:0 (包括整数、浮点数、复数等)。
- 布尔类型:False。
- 字符串类型:空字符串 ""。
- 序列类型:空列表 []、空元组 ()、空集合 set()。
- 映射类型:空字典 {}。
- None 类型:None。
其他非空、非零的值都会被转换为 True。
print(bool(0)) #False
print(bool(0.0)) #False
print(bool("")) #False
print(bool([])) #False
print(bool(())) #False
print(bool({})) #False
print(bool(None)) #False
第六章、str 字符串
一、概述
在 Python 中,字符串是一种用于表示文本数据的数据类型,它是不可变的(immutable)序列,可以包含字符、数字和符号等数据。字符串是 Python 中最常用的数据类型之一,它有丰富的内置方法和操作,用于处理文本数据。
- str表示字符串类型,属于引用数据类型,Python中没有基本数据类型
- 在Python中随意使用单引号或双引号括起来的都是str对象。例如:“abc”,‘def’,都是str对象
- Python中规定,字符串是不可变的,也就是说“abc”自出生到死亡,都是不可变的。
1、字符串不区分单双引号
在 Python 中,字符串既可以使用单引号 ' '
来表示,也可以使用双引号 " "
来表示。这意味着你可以根据需要使用单引号或双引号来创建字符串,两种方式在语法上是等价的,没有区别。以下是一些示例来说明这一点:
single_quoted_string = 'This is a string using single quotes.'
double_quoted_string = "This is a string using double quotes."
print(single_quoted_string)
print(double_quoted_string)
在上面的示例中,single_quoted_string
和 double_quoted_string
都是字符串变量,它们的内容分别由单引号和双引号包围。
这种灵活性使得在 Python 中编写字符串变得更加方便,因为你可以根据上下文选择使用更方便的引号来创建字符串。例如,如果字符串中包含了引号,你可以在使用引号字符的地方使用不同类型的引号来创建字符串,避免转义字符的使用。例如:
string_with_quotes = "He said, 'Hello!'"
another_string = 'She replied, "Hi there!"'
print(string_with_quotes)
print(another_string)
总之,Python 中的字符串既可以使用单引号也可以使用双引号来表示,这为字符串的编写提供了更大的灵活性。
2、字符串不可变解释
在 Python 中,字符串(String)是不可变的数据类型,这意味着一旦创建了字符串对象,就不能更改它的内容。当你对字符串进行操作(例如连接、截取、替换等),实际上是创建了一个新的字符串对象,而不是在原始的字符串对象上进行修改。
这种字符串不可变性的特性具有一些重要的影响和优势:
-
保证数据的安全性: 不可变性确保了字符串内容在创建后不能被意外修改,从而避免了在程序运行时发生意外的数据更改。
-
优化内存使用: 由于字符串不可变,Python 可以在适当的情况下共享字符串的内存,从而减少内存的使用,提高性能。
-
多线程安全: 字符串的不可变性使得多线程操作字符串时不会出现竞争条件,从而减少了线程安全问题。
下面是一些示例来说明字符串的不可变性:
original_string = "Hello"
modified_string = original_string + ", World!" # 创建新的字符串对象
print(original_string) # 输出仍然是 "Hello"
print(modified_string) # 输出 "Hello, World!"
在上面的示例中,我们对 original_string
进行了连接操作,得到了一个新的字符串 modified_string
。原始的字符串 original_string
的内容没有被修改,仍然保持不变。
总之,Python 中的字符串不可变性确保了字符串对象一旦创建就不会被修改,这种特性在编程中有很多优势,包括数据的安全性、内存优化和线程安全。
3、字符串对象内存优化
在 Python 中,字符串对象的内存管理和优化机制与 Java 中的字符串常量池有些不同,但有一些相似之处。虽然 Python 没有像 Java 那样的字符串常量池,但在一些情况下,Python 也会进行字符串对象的内存共享和优化。
在 Python 中,字符串对象的内存优化主要依赖于以下两个机制:
-
字符串的共享: 在 Python 中,相同的字符串字面值在内存中只会被存储一次。这种共享机制类似于字符串常量池,但并不完全相同。当你创建一个字符串时,如果该字符串的值已经存在,Python 会直接引用已经存在的对象,而不是创建一个新的对象。
-
小字符串的优化: Python 会对较短的字符串进行优化,将它们放入一个内部的缓存中,以便在多次创建相同短字符串时可以直接引用缓存中的对象,减少内存使用。
在 Python 中,通常情况下,字符串对象会在堆中分配一块内存来存储字符串的值。这意味着字符串对象本身的内存空间包含指向实际字符串数据的指针。
然而,在 Python 3.7 及以后的版本中,对于长度小于等于 20 个字符的字符串,采用了一种优化技术,即 "Small String Optimization"(SSO),使得字符串对象本身可以直接存储字符串的值,而不需要额外的内存分配。
具体实现方式是:
-
对于较短的字符串,Python 会将字符串的值直接存储在字符串对象本身的内存空间中,而不是在堆中分配额外的内存。这样做的好处是避免了为每个短字符串额外分配内存所带来的开销。
-
当字符串长度超过 20 个字符时,Python 会切换回传统的方式,在堆中分配内存来存储字符串的值。
这种优化技术可以提高处理短字符串的性能和节省内存空间,因为很多时候我们会使用较短的字符串,而且不需要为它们分配额外的内存空间。
需要注意的是,这是 Python 解释器的内部优化,对于使用 Python 的开发者来说,并不需要关心这些细节,因为 Python 会自动处理这些内存管理的问题。
以下是一个示例,说明 Python 中字符串对象的内存优化机制:
str1 = "Hello"
print(id(str1)) #2682449142480
str2 = "Hello"
print(id(str2)) #2682449142480
print(str1 is str2) # 输出 True,因为相同的字符串字面值被共享
long_string1 = "This is a long string with a lot of characters."
print(id(long_string1)) #2682449037328
long_string2 = "This is a long string with a lot of characters."
print(id(long_string2)) #2682449037328
print(long_string1 is long_string2) # 输出 True,因为相同的字符串字面值被共享
需要注意的是,字符串对象的共享和优化在某些情况下可以降低内存使用,但并不是在所有情况下都会发生。例如,当你对字符串进行操作时(例如切片、拼接等),可能会生成新的字符串对象,而不再共享原始对象。
总之,Python 中没有像 Java 那样的字符串常量池,但字符串对象的内存管理机制在一些情况下会进行优化,包括共享相同的字符串字面值和对短字符串的优化。
4、字符串对象是可索引,可迭代的
在 Python 中,字符串对象是可索引和可迭代的。这意味着你可以通过索引访问字符串中的单个字符,也可以使用循环来迭代字符串中的每个字符。
可索引性(Indexing): 你可以使用索引来访问字符串中的特定位置的字符。索引从 0 开始,表示第一个字符,1 表示第二个字符,依此类推。
my_string = "Hello, World!"
first_char = my_string[0] # 获取第一个字符 'H'
second_char = my_string[1] # 获取第二个字符 'e'
可迭代性(Iteration): 你可以使用 for
循环来迭代字符串中的每个字符
my_string = "Hello"
for char in my_string:
print(char) # 逐个输出 'H', 'e', 'l', 'l', 'o'
字符串作为一个序列类型,在 Python 中是支持索引和迭代的,这使得你可以方便地处理字符串中的字符。
二、创建字符串对象
1、使用单引号或双引号: 使用单引号 ' '
或双引号 " "
来创建字符串对象
string1 = 'Hello, World!'
string2 = "Python is awesome!"
2、使用 str() 构造函数: 使用 str()
构造函数将其他数据类型转换为字符串
number = 42
number_string = str(number) # 将数字转换为字符串
三、访问字符串中的值
在 Python 中,字符串索引和切片是用来访问和操作字符串中字符的重要方式。索引用于获取单个字符,而切片用于获取子字符串。下面详细解释字符串索引和切片的使用方式:
1、字符串索引
字符串索引: 字符串中的每个字符都有一个与之关联的索引,索引从 0 开始,依次递增。负数索引表示从字符串末尾开始计数,-1 表示最后一个字符,-2表示倒数第二个字符,依次类推。
my_string = "Hello, World!"
# 使用正数索引获取字符
first_char = my_string[0] # 返回 "H"
third_char = my_string[2] # 返回 "l"
# 使用负数索引获取字符
last_char = my_string[-1] # 返回 "!"
second_last_char = my_string[-2] # 返回 "d"
1.1、字符串索引实现原理
类型:def __getitem__(self, i: int | slice) -> str: ...
Python 中字符串的索引访问实际上是通过特殊方法 __getitem__
来实现的。__getitem__
方法允许对象在使用索引访问时进行自定义行为。
当你通过索引访问字符串中的字符时,Python 实际上会调用字符串对象的 __getitem__
方法来获取对应的字符。这也是 Python 中的魔术方法之一,用于实现自定义的索引访问逻辑。
以下是一个示例,说明字符串的索引访问是如何通过 __getitem__
方法来实现的:
class MyString:
def __init__(self, value):
self.value = value
def __getitem__(self, index):
return self.value[index]
# 创建自定义字符串对象
my_string = MyString("Hello, World!")
# 使用索引访问
first_char = my_string[0] # 调用了 my_string.__getitem__(0)
print(first_char) # 输出 "H"
在上面的示例中,自定义的 MyString
类实现了 __getitem__
方法,使得可以通过索引来访问字符串中的字符,就像在标准的字符串对象上一样。
需要注意的是,Python 的内置字符串类型也是使用类似的机制来实现索引访问。当你对内置字符串类型使用索引时,实际上也是在调用字符串类的
__getitem__
方法。
1.2、IndexError
字符串索引越界异常,当传入的索引大于字符串的最大索引时会引发该异常
2、字符串切片
切片允许你从字符串中获取子字符串。切片语法使用起始索引、结束索引和步长来指定子字符串的范围。
语法:
字符串名[起始索引:结束:步长]
- 起始索引:从哪个位置开始截取,可省略,默认为0
- 结束:从哪个位置结束,左闭右开,可省略,默认为字符串长度,到字符串末尾
- 步长:相邻两个索引位置之差,可省略,默认为1
- 从左到右,步长为正;从右到左,步长为负
左闭右开或前闭后开,即起始索引处为闭,结束处为开;从左到右依次优先起始,结束,一般省略步长,否则要加冒号:
若是索引访问,索引越界,会报出indexerror,若是切片时索引越界不会导致indexerror,只会返回空,什么都没有的
my_string = "Hello, World!"
# 使用切片获取子字符串
substring1 = my_string[7:12] # 返回 "World"
substring2 = my_string[0:5] # 返回 "Hello"
substring3 = my_string[:5] # 省略起始索引,默认从开头开始
substring4 = my_string[7:] # 省略结束索引,默认到末尾
substring5 = my_string[::2] # 步长为2,获取每隔一个字符的子字符串,返回 "Hlo ol!"
需要注意的是,切片操作是左闭右开区间,即包含起始索引对应的字符,但不包含结束索引对应的字符。
另外,字符串是不可变的,这意味着你不能直接通过索引或切片来修改字符串中的字符。如果需要修改字符串,你需要创建一个新的字符串。
# 不能直接修改字符串
# my_string[0] = 'h' # 会导致错误
# 创建新的字符串
new_string = 'h' + my_string[1:] # 替换第一个字符为小写 "h"
总之,字符串索引和切片是在 Python 中处理字符串中字符和子字符串的常见方式。通过索引和切片,你可以获取你所需的部分并进行相应的处理。
2.1、字符串切片实现原理
在 Python 中,字符串切片操作实际上是通过特殊方法 __getitem__
结合切片对象来实现的。Python 使用切片对象来表示切片操作的范围,并将其作为参数传递给 __getitem__
方法。
当你使用切片操作来获取字符串的子字符串时,Python 会将切片对象传递给字符串对象的 __getitem__
方法,然后你可以根据切片对象的属性来计算切片的范围。
以下是一个示例,说明字符串的切片操作是如何通过 __getitem__
方法和切片对象来实现的:
class MyString:
def __init__(self, value):
self.value = value
def __getitem__(self, slice_obj):
if isinstance(slice_obj, slice):
start = slice_obj.start or 0
stop = slice_obj.stop or len(self.value)
step = slice_obj.step or 1
return self.value[start:stop:step]
elif isinstance(slice_obj, int):
return self.value[slice_obj]
else:
raise TypeError("Unsupported slice type")
# 创建自定义字符串对象
my_string = MyString("Hello, World!")
# 使用切片访问
substring = my_string[7:12] # 调用了 my_string.__getitem__(slice(7, 12, None))
print(substring) # 输出 "World"
在上面的示例中,自定义的 MyString
类实现了 __getitem__
方法,可以处理切片对象和整数索引。当使用切片操作时,Python 会将切片对象传递给 __getitem__
方法,然后你可以通过切片对象的属性来获取切片的范围。
需要注意的是,Python 的内置字符串类型也是使用类似的机制来实现切片操作。当你对内置字符串类型使用切片操作时,实际上也是在调用字符串类的 __getitem__
方法,并传递一个切片对象作为参数。
2.2、切片实现java中的startsWith和endsWith方法
在 Python 中,字符串对象没有类似于 Java 中的 startsWith
和 endsWith
方法。然而,你可以使用字符串的切片操作来实现类似的功能。
类似于 startsWith
方法: Java 中的 startsWith
方法用于检查字符串是否以指定的前缀开头。在 Python 中,你可以使用字符串的切片操作来检查字符串的开头部分是否与指定的前缀匹配。
string = "Hello, World!"
prefix = "Hello"
starts_with = string[:len(prefix)] == prefix
print(starts_with) # 输出 True
类似于 endsWith
方法: Java 中的 endsWith
方法用于检查字符串是否以指定的后缀结尾。在 Python 中,你可以使用字符串的切片操作来检查字符串的末尾部分是否与指定的后缀匹配。
string = "Hello, World!"
suffix = "World!"
ends_with = string[-len(suffix):] == suffix
print(ends_with) # 输出 True
虽然 Python 没有直接的 startsWith
和 endsWith
方法,但通过切片操作可以很容易地实现类似的功能。需要注意的是,这些示例假设你已经检查了字符串长度以防止越界。
四、字符串的运算
1、+:将指定的字符串连接到原始字符串的末尾(类似于java中的concat方法)
底层调用:def __add__(self, s: str) -> str: ...
因此只能字符串与字符串相加,数字与数字相加,字符串与数据相加需要将数字强制类型转换为字符串
string1 = "Hello, "
string2 = "World!"
concatenated_string = string1 + string2 # 创建新的字符串 "Hello, World!"
2、*:将字符串重复几遍
在 Python 中,字符串的 *
运算符用于重复一个字符串多次,创建一个新的字符串。这个运算符使你可以简单地将一个字符串复制多次,从而生成一个新的字符串。
语法:
new_string = original_string * n
其中,original_string
是要重复的原始字符串,而 n
是重复的次数。
以下是一个例子,说明字符串的 *
运算符是如何工作的:
original_string = "ABC"
repeated_string = original_string * 3 # 创建新的字符串 "ABCABCABC"
在底层,字符串的 *
运算符调用了字符串的 __mul__
方法,这是 Python 的一种魔术方法,用于实现重复操作。下面是一个自定义字符串类的示例,演示了如何实现类似的重复操作:
class MyString:
def __init__(self, value):
self.value = value
def __mul__(self, n):
if isinstance(n, int):
return self.value * n
else:
raise TypeError("Unsupported multiplication")
original_string = MyString("ABC")
repeated_string = original_string * 3 # 调用了 original_string.__mul__(3)
print(repeated_string) # 输出 "ABCABCABC"
在这个示例中,自定义的 MyString
类实现了 __mul__
方法,允许字符串对象重复多次。当使用 *
运算符进行重复时,Python 会调用 __mul__
方法来执行实际的操作。
需要注意的是,内置的字符串类型也实现了 __mul__
方法,因此你可以直接使用 *
运算符来进行字符串的重复操作。
3、==:判断字符串是否内容(值)相等,相等返回Ture不相等返回False
底层调用:def __eq__(self, x: object) -> bool: ...
s1 = "jzq"
s2 = "jzq"
s3 = "jzq2"
print(s1 == s2) #True
print(s1 == s3) #False
实现判断字符串是否为空:
def isEmpty(s):
if len(s) == 0:
return True
return False
4、in和not in运算符
in:判断某个字符串是否在另一个字符串中,在为Ture,不在为False
not in:判断某个字符串是否不在另一个字符串中,不在为Ture,在为False
在 Python 中,字符串对象支持 in
和 not in
运算符,用于检查一个字符串是否包含另一个子字符串。这两个运算符提供了一种简单的方法来判断字符串中是否存在指定的子字符串。
语法:
substring in string
substring not in string
其中,substring
是要检查的子字符串,而 string
是要搜索的字符串。
以下是详细说明和示例:
in
运算符: 如果子字符串存在于字符串中,返回 True
;否则返回 False
。
string = "Hello, World!"
is_contained1 = "World" in string # 返回 True
is_contained2 = "Python" in string # 返回 False
not in
运算符: 如果子字符串不存在于字符串中,返回 True
;否则返回 False
。
string = "Hello, World!"
is_not_contained1 = "World" not in string # 返回 False
is_not_contained2 = "Python" not in string # 返回 True
在底层,in
和 not in
运算符调用了字符串的 __contains__
方法,这是 Python 的一种魔术方法,用于判断对象是否包含指定的元素。下面是一个示例,演示了如何在自定义字符串类中实现类似的功能:
class MyString:
def __init__(self, value):
self.value = value
def __contains__(self, substring):
return substring in self.value
string = MyString("Hello, World!")
is_contained = "World" in string # 调用了 string.__contains__("World")
is_not_contained = "Python" not in string #调用了 string.__contains__("Python")
print(is_contained) # 输出 True
print(is_not_contained) #输出 True
在这个示例中,自定义的 MyString
类实现了 __contains__
方法,允许检查一个字符串是否包含指定的子字符串。当使用 in
或 not in
运算符时,Python 会调用 __contains__
方法来执行实际的检查。
5、比较运算符
1、字典顺序:a b c d e f g ....... 从前往后依次增大
2、拿着第一个字符串的相同位置字符和后面字符串的相同位置字符进行比较,若能分出大小,则后续就不用比较了
返回True或False
在 Python 中,没有直接类似于 Java 中的 compareTo
方法的内置方法。Java 中的 compareTo
方法用于比较两个对象的大小关系,例如比较两个字符串的字典顺序。
在 Python 中,如果你想比较两个对象的大小关系,可以使用比较运算符(如 <
、<=
、>
、>=
、==
、!=
)来完成。这些比较运算符可以用于比较数字、字符串等类型的对象。
如果你想在自定义的类中实现类似于 compareTo
的功能,可以在类中定义
__lt__
(小于)less-than__le__
(小于等于)less than or equal to__gt__
(大于)greater than__ge__
(大于等于)great than or equal to__eq__
(等于)equal to__ne__
(不等于)not equal to
等魔术方法,以便对象可以被正确地比较。
以下是一个示例,演示了如何在 Python 中使用比较运算符和自定义魔术方法进行对象比较:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
return self.age < other.age
def __eq__(self, other):
return self.age == other.age
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
print(person1 < person2) # 输出 True,因为 person1 的年龄小于 person2 的年龄
print(person1 == person2) # 输出 False,因为两人年龄不相等
在上述示例中,Person
类定义了 __lt__
和 __eq__
方法,允许对象通过比较运算符进行比较。需要根据实际情况自定义这些方法来实现对象的比较逻辑。
五、格式化字符串
占位符之间可穿插任意字符及符号
1、%
格式化
语法:
“ 给定格式 ” %(要输出的内容1,内容2,......) 要一一对应起来
%
格式化中的格式控制字符串可以包含多个选项,用于定义要插入到字符串中的变量的格式。这个格式控制字符串的一般结构是 %[name][flags][width][.][precision][type]
,其中每个部分都是可选的。
-
%[name]
: 这是一个可选的命名字段,用于引用将在后面传递给printf()
(或sprintf()
)函数的参数。在 Python 的字符串格式化中,这通常不使用,因此我们在这里不详细介绍。 -
%[flags]
: 这是一个可选的标志,用于控制插入值的格式。常用的标志有:-
: 将输出左对齐。+
: 将正数前加上正号+
。0
: 将值用零填充,而不是默认的空格填充。- (空格): 在正数前加上空格,而不是
+
。
-
%[width]
: 这是一个可选的字段宽度,用于指定输出字段的最小宽度。如果值的长度小于宽度,则在值的左侧使用填充字符填充(默认是空格)。例如,%5d
将使得插入的整数至少占 5 个字符宽度。 -
%.
: 这是可选的小数点(点号),用于指示精度。后面可以跟一个数字,表示小数部分的位数。例如,%.2f
将确保浮点数至少有 2 位小数。 -
%[precision]
: 用于指定浮点数的小数位数,与.precision
相同。 -
%[type]
: 用于指定插入值的数据类型。常用的类型有:d
或i
: 整数。f
: 浮点数。s
: 字符串。x
或X
: 十六进制整数。c
: 字符。
示例:
name = "Alice"
age = 30
height = 1.75
message = "My name is %s, I am %d years old, and I am %.2f meters tall." % (name, age, height)
print(message)
# 输出: My name is Alice, I am 30 years old, and I am 1.75 meters tall.
在这个示例中,%s
、%d
和 %.2f
分别是字符串、整数和浮点数的格式化控制。
特殊案例:
print(’%.2f'%123)---123.00
print('%.5d'%123) --- 00123
2、.format()
方法
print('{}{}...'.format(a,b...)) a,b为变量名,前后顺序须一一对应
.format()
方法是一种更灵活的字符串格式化方法,它使用大括号 {}
标记要插入的位置,并通过 .format()
方法传递变量的值。
示例:
name = "Bob"
score = 85
message = "Hello, my name is {} and my score is {}.".format(name, score)
print(message) # 输出: Hello, my name is Bob and my score is 85.
3、f-strings(格式化字符串字面值)
f-strings 是从 Python 3.6 开始引入的一种字符串格式化方法,它允许您在字符串前加上 f
,并在字符串中直接使用变量名。使用 f-strings 可以使格式化字符串更加简洁和直观。
示例:
name = "Charlie"
age = 25
message = f"My name is {name} and I am {age} years old."
print(message) # 输出: My name is Charlie and I am 25 years old.
六、转义字符
在 Python 中,转义字符用于在字符串中插入特殊字符,这些特殊字符在正常情况下无法直接输入。转义字符以反斜杠 \
开头,后面跟着一个或多个字符,用来表示特定的字符。下面是一些常见的转义字符及其含义:
\\
: 反斜杠,用于插入一个反斜杠字符。\'
: 单引号,用于插入一个单引号字符。\"
: 双引号,用于插入一个双引号字符。\n
: 换行,用于在字符串中插入一个换行符。\t
: 制表符,用于插入一个水平制表符(Tab)。\r
: 回车,用于插入一个回车符。\b
: 退格,用于插入一个退格符。\f
: 换页,用于插入一个换页符。
print("Hello\nWorld") # 输出:
# Hello
# World
print("=" * 30)
print("hello\rworld") #输出:world
print("=" * 30)
print("Hello\tWorld") # 输出: Hello World
print("=" * 30)
print("This is a single quote: \'") # 输出: This is a single quote: '
print("=" * 30)
print("This is a double quote: \"") # 输出: This is a double quote: "
1、路径表示
\\:表示路径
r:字符串前加r,保留原有意思,不会有转义了
需要注意的是,转义字符通常在字符串中用于表示无法直接输入的特殊字符,比如换行符、制表符等。在需要输出包含反斜杠本身的字符串时,可以使用双反斜杠 \\
,或者使用原始字符串(在字符串前加上 r
或 R
)。
print("This is a backslash: \\") # 输出: This is a backslash: \
print(r"This is a backslash: \\") # 输出: This is a backslash: \\
七、常用属性和方法
1、__len__():返回字符串的长度,即字符串中字符的个数
s = "Hello"
print(s.__len__()) #5
#等同于
print(len(s)) #5
2、upper()
方法:将字符串中的所有字符转换为大写形式,并返回一个新的字符串。
类型:def upper(self) -> str: ...
original_string = "Hello, World!"
uppercased_string = original_string.upper() # 调用了 original_string.__upper__()
print(uppercased_string) # 输出 "HELLO, WORLD!"
3、lower()
方法:将字符串中的所有字符转换为小写形式,并返回一个新的字符串。
类型:def lower(self) -> str: ...
original_string = "Hello, World!"
lowercased_string = original_string.lower()
print(lowercased_string) # 输出 "hello, world!"
忽略大小写进行字符串比较
在 Python 中,字符串对象没有类似于 Java 中的 equals
和 equalsIgnoreCase
方法。在 Java 中,equals
方法用于比较两个字符串是否相等,而 equalsIgnoreCase
方法用于比较两个字符串在忽略大小写的情况下是否相等。
在 Python 中,字符串的比较通常使用 ==
运算符来完成。==
运算符比较两个字符串的内容是否相等。如果你希望在比较字符串时忽略大小写,可以使用 str.lower()
或 str.upper()
方法来将字符串转换为统一的大小写形式,然后进行比较。
以下是一个示例,演示如何在 Python 中进行字符串比较以及如何忽略大小写:
string1 = "Hello, World!"
string2 = "hello, world!"
# 使用 == 运算符比较字符串内容
is_equal = string1 == string2 # 返回 False,因为大小写不同
# 使用 lower() 方法比较忽略大小写
is_equal_ignore_case = string1.lower() == string2.lower() # 返回 True,因为忽略大小写后内容相同
print(is_equal) #False
print(is_equal_ignore_case) #True
需要注意的是,Python 的字符串比较是区分大小写的,因此直接使用 ==
运算符比较两个字符串时,会考虑大小写的差异。如果你需要在比较时忽略大小写,可以使用类似于上述示例中的方法进行转换和比较。
4、title()
方法:将字符串中的每个单词的首字母转换为大写形式,并返回一个新的字符串。
类型:def title(self) -> str: ...
original_string = "hello, world!"
titled_string = original_string.title()
print(titled_string) # 输出 "Hello, World!"
5、capitalize()
方法:将字符串的首字母转换为大写形式,其余字符转换为小写形式,并返回一个新的字符串。
类型:def capitalize(self) -> str: ...
original_string = "hello, world!"
capitalized_string = original_string.capitalize()
print(capitalized_string) # 输出 "Hello, world!"
6、strip()
方法:从字符串的开头和结尾移除指定的字符(默认为空格及换行符)并返回新的字符串。
类型:def strip(self, __chars: str | None = ...) -> str: ...
源码:默认为空格,传入其他字符串也可以
def strip(self, chars=None): # real signature unknown; restored from __doc__
"""
S.strip([chars]) -> str
Return a copy of the string S with leading and trailing
whitespace removed.
If chars is given and not None, remove characters in chars instead.
"""
return ""
用法:
original_string = " Hello, World! "
stripped_string = original_string.strip()
print(stripped_string) # 输出 "Hello, World!"
会自动匹配删除a,b所有的组合
7、rstrip()
方法:从字符串的结尾移除指定的字符(默认为空格)并返回新的字符串。
类型:def rstrip(self, __chars: str | None = ...) -> str: ...
original_string = " Hello, World! "
stripped_string = original_string.rstrip()
print(stripped_string) # 输出 " Hello, World!"
8、lstrip()
方法:从字符串的开头移除指定的字符(默认为空格)并返回新的字符串。
类型:def lstrip(self, __chars: str | None = ...) -> str: ...
original_string = " Hello, World! "
stripped_string = original_string.lstrip()
print(stripped_string) # 输出 "Hello, World! "
9、find()
方法:在字符串中查找指定子字符串的第一次出现,并返回其索引位置。如果子字符串不存在,返回 -1
从左到右查找:find()
find():检查字符串中是否包含指定的子字符串,包含则返回(子字符串从左到右的第一个字符的)在原字符串中首次出现的索引值,否则返回-1
str1.find(str2,start,end)
- str1:在哪个字符串中查找(只能是字符串)
- str2:统计的子字符串
- start:开始索引 end:结束索引 都可省略
如果要查找的子字符串不存在,
find()
和rfind()
方法会返回 -1,而index()
和rindex()
方法会引发异常。
源码:
def find(self, sub, start=None, end=None): # real signature unknown; restored from __doc__
"""
S.find(sub[, start[, end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within S[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
"""
return 0
用法:
string = "Hello, World!"
substring = "World"
index = string.find(substring) # 返回 7
10、rfind()
方法:在字符串中查找指定子字符串的最后一次出现,并返回其索引位置。如果子字符串不存在,返回 -1。
从右到左查找:rfind()
rfind():检查字符串中是否包含指定的子字符串,包含则返回(子字符串从左到右的第一个字符的)在原字符串中最后一次出现的索引值,否则返回-1
str1.rfind(str2,start,end)
- str1:在哪个字符串中查找(只能是字符串)
- str2:统计的子字符串
- start:开始索引 end:结束索引 都可省略
string = "Hello, World! Hello!"
substring = "Hello"
last_index = string.rfind(substring) # 返回 13
11、index()
方法:在字符串中查找指定子字符串的第一次出现,并返回其索引位置。如果子字符串不存在,会引发 ValueError
异常。
string = "Hello, World!"
substring = "World"
index = string.index(substring) # 返回 7
12、rindex()
方法:在字符串中查找指定子字符串的最后一次出现,并返回其索引位置。如果子字符串不存在,会引发 ValueError
异常。
string = "Hello, World! Hello!"
substring = "Hello"
last_index = string.rindex(substring) # 返回 14
13、replace()方法:将字符串中的所有指定子字符串替换为另一个字符串,并返回一个新的字符串。原始字符串不会被修改。
语法:
new_string = old_string.replace(old_substring, new_substring, count)
old_substring
:要被替换的子字符串。new_substring
:用来替换的新子字符串。count
(可选):指定替换的最大次数,不指定时会替换所有匹配项。
original_string = "Hello, World!"
new_string = original_string.replace("World", "Python")
print(new_string) # 输出 "Hello, Python!"
14、encode()
方法:将字符串转换为字节序列(字节数组),并指定字符编码。
在 Python 中,没有直接类似于 Java 中的 getBytes
方法的内置方法。Java 中的 getBytes
方法用于将字符串转换为字节数组,可以指定字符编码。
在 Python 中,你可以使用字符串的 encode()
方法来将字符串转换为字节序列(字节数组),并指定字符编码。下面是一个示例:
text = "abc"
# 将字符串转换为字节序列(字节数组)使用 UTF-8 编码
byte_array = text.encode("utf-8")
print(byte_array) # 输出字节序列的表示形式 b'abc'
for i in byte_array:
print(i)
"""
97
98
99
"""
在上述示例中,encode("utf-8")
方法将字符串转换为字节序列,使用 UTF-8 编码。你可以选择不同的字符编码,如 UTF-8、UTF-16、ISO-8859-1 等。
15、split()
方法:将字符串根据指定的分隔符进行分割,并返回一个包含分割后子字符串的列表。
将字符串分割为列表,分隔符不会作为一个元素放在列表中
默认从左到右依次分割
- 语法:
string.split(sep, maxsplit)
sep
(可选):用于分割的分隔符,默认为所有空白字符(空格、制表符、换行等)。maxsplit
(可选):指定最大分割次数,超过该次数后不再分割,默认为无限制。
- 返回值:一个包含分割后子字符串的列表。
text = "apple,banana,orange,grape"
fruits = text.split(',') # 使用逗号作为分隔符
print(fruits) # 输出: ['apple', 'banana', 'orange', 'grape']
sentence = "This is a sample sentence."
words = sentence.split() # 使用空格作为分隔符
print(words) # 输出: ['This', 'is', 'a', 'sample', 'sentence.']
在上面的例子中,split
方法将字符串分割成了多个子字符串,并将这些子字符串存储在列表中。
需要注意的是,
split
方法不会修改原始字符串,而是返回一个新的列表。如果需要移除字符串中的空白或空字符,可以使用strip()
方法先进行处理。
split() 和 split(" ")的区别:
s = " I like Python "
"""
因为 split(" ") 方法在默认情况下会将字符串的开头和结尾的分隔符看作是空字符串,
并将其包含在结果列表中。在您的字符串中,开头有两个空格,
末尾有一个空格,因此会产生两个空字符串的项。
"""
print(s.split(" ")) #['', '', 'I', 'like', 'Python', '']
print(s.split()) #['I', 'like', 'Python']
16、list()方法:将字符串转换为字符列表
在 Java 中,toCharArray()
方法用于将字符串转换为字符数组。在 Python 中,字符串本身就类似于字符数组,因此没有直接的方法来转换成字符数组,因为字符串可以像数组一样访问单个字符。
在 Python 中,您可以通过以下方式获得类似的效果:
string = "hello"
char_array = list(string) # 将字符串转换为字符列表
print(char_array) # 输出: ['h', 'e', 'l', 'l', 'o']
在这里,list(string)
的操作将字符串中的每个字符分割并存储在一个列表中,这就达到了类似于 Java 中 toCharArray()
方法的效果。
需要注意的是,虽然 Python 中字符串和列表之间的转换是常见且简单的操作,但在大多数情况下,您不需要将字符串转换为字符列表,因为 Python 的字符串本身就具备了许多列表操作的功能,例如遍历、索引和切片。
例如,您可以像下面这样通过索引来访问字符串中的单个字符:
string = "hello"
first_char = string[0] # 获取第一个字符 "h"
您可以使用切片来获取字符串的子串:
substring = string[1:4] # 获取索引 1 到 3 的子串 "ell"
因此,在 Python 中,您可以直接使用字符串的内置方法和特性来完成大多数与字符数组相关的操作,而无需显式地将其转换为字符列表。
17、join()
方法将一个列表(或其他可迭代对象)中的元素拼接成一个字符串
类型: def join(self, __iterable: Iterable[str]) -> str: ...
语法:
separator.join(iterable)
separator
: 这是一个字符串,用于指定连接每个元素之间的分隔符。iterable
: 这是一个可迭代对象,比如列表、元组、集合等,其中的元素将会被连接起来。
返回值
join()
方法返回一个新的字符串,其中包含从可迭代对象中的元素连接而成的内容。
示例
my_list = ['apple', 'banana', 'orange', 'grape']
delimiter = ', ' # 分隔符
result_string = delimiter.join(my_list)
print(result_string) # 输出: "apple, banana, orange, grape"
在上面的示例中,delimiter.join(my_list)
将列表 my_list
中的元素用 ,
分隔符连接起来,形成了一个新的字符串。
numbers = ['1', '2', '3', '4']
separator = ' - '
number_string = separator.join(numbers)
print(number_string) # 输出: "1 - 2 - 3 - 4"
在这个示例中,separator.join(numbers)
将数字列表中的元素用 ' - '
分隔符连接起来,形成了一个新的字符串。
需要注意的是,join()
方法通常在大量字符串拼接的情况下更加高效,因为它避免了创建临时中间字符串的开销。而在循环中通过字符串拼接可能会导致性能下降。
18、isalnum()
方法:用于检查字符串是否只包含字母或数字或汉字
如果字符串中的所有字符都是字母或数字或汉字,则返回
True
,否则返回False
。判断字符串里面的字母与数字,一个字符就是一个字符串,同样适用来判断
s1 = "jzq"
print(s1.isalnum()) #True
s2 = "123"
print(s2.isalnum()) #True
s3 = "贾卓群"
print(s3.isalnum()) #True
s4 = "-+"
print(s4.isalnum()) #False
19、isalpha():
用于检查字符串是否只包含字母字符
如果字符串中的所有字符都是字母,则返回
True
,否则返回False
。
text = "Hello"
result = text.isalpha() # 返回 True,因为字符串只包含字母
20、isdigit()
方法:用于检查字符串是否只包含数字字符
如果字符串中的所有字符都是数字,则返回
True
,否则返回False
。
text = "12345"
result = text.isdigit() # 返回 True,因为字符串只包含数字
21、startswith()
方法:用于检查字符串是否以指定的子字符串开头
如果字符串以指定的子字符串开头,则返回
True
,否则返回False
。
类型:
def startswith(
self, __prefix: str | Tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...
) -> bool: ...
语法:
string.startswith(prefix, start, end)
prefix
: 这是要检查的子字符串,用于判断字符串是否以它开头。start
: 这是可选参数,用于指定开始检查的索引位置,默认为 0。end
: 这是可选参数,用于指定结束检查的索引位置,默认为字符串的长度。
示例:
text = "Hello, World!"
result = text.startswith("Hello") # 返回 True
22、endswith()
方法:用于检查字符串是否以指定的子字符串结尾
如果字符串以指定的子字符串结尾,则返回
True
,否则返回False
。
类型:
def endswith(
self, __suffix: str | Tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...
) -> bool: ...
语法:
string.endswith(suffix, start, end)
suffix
: 这是要检查的子字符串,用于判断字符串是否以它结尾。start
: 这是可选参数,用于指定开始检查的索引位置,默认为 0。end
: 这是可选参数,用于指定结束检查的索引位置,默认为字符串的长度。
str.endswith("suffix", => 后缀,可以是单个字符,也可以是字符串,还可以是元组;
start=0, => 索引字符串的起始位置;
end=len(str) => 索引字符串的结束位置。)
返回值:布尔类型(True,False)
示例:
str = "i love python"
#True
print("1:",str.endswith("n"))
#True
print("2:",str.endswith("python"))
#False
print("3:",str.endswith("n",0,6))# 索引 i love 是否以“n”结尾。
#True
print("4:",str.endswith("")) #空字符
#False
print("5:",str[0:6].endswith("n")) # 只索引 i love
#True
print("6:",str[0:6].endswith("e"))
#True
print("7:",str[0:6].endswith(""))
#True
print("8:",str.endswith(("n","z")))#遍历元组的元素,存在即返回True,否者返回False
#False
print("9:",str.endswith(("k","m")))
#元组案例
file = "python.txt"
if file.endswith("txt"):
print("该文件是文本文件")
elif file.endswith(("AVI","WMV","RM")):
print("该文件为视频文件")
else:
print("文件格式未知")
23、center()
方法:用于将字符串在指定宽度内居中对齐,并使用指定的填充字符(默认为空格)填充剩余的空白位置。
- 返回一个原字符串居中,并使用填充字符将原字符串填充至长度width的新字符串,默认填充字符为空格。
- 空余长度是奇数的情况下会按照左少右多的规律进行字符填充
语法:
string.center(width, fillchar)
width
: 这是一个整数,表示字符串的总宽度,包括原始字符串和填充字符。fillchar
: 这是一个可选参数,用于指定填充字符。默认情况下是空格字符。
返回值
center()
方法返回一个新的字符串,其中包含了原始字符串在指定宽度内居中对齐的结果。
示例
text = "Hello"
centered_text = text.center(20, '-') # 在宽度为 20 的空间内居中对齐,使用 "-" 填充
print(centered_text) # 输出: ------Hello-------
在这个示例中,centered_text
是一个长度为 20 的新字符串,其中包含了原始字符串 "Hello"
在中间对齐的结果,用 "-" 填充了剩余的空白位置。
word = "Python"
centered_word = word.center(15) # 在宽度为 15 的空间内居中对齐,默认使用空格填充
print(centered_word) # 输出: Python
在这个示例中,默认使用空格填充了剩余的空白位置,使得字符串 "Python"
在宽度为 15 的空间内居中对齐。
center()
方法在格式化输出、美化文本表格等情况下非常有用,可以让文本内容更加整齐、漂亮地显示在指定宽度的空间内。
八、str类型转换(str() 构造方法)
1、将int类型转换为str类型
print(type(123)) #<class 'int'>
print(type(str(123))) #<class 'str'>
2、将float类型转换为str类型
print(type(3.14)) #<class 'float'>
print(type(str(3.14))) #<class 'str'>
3、将bool类型转换为str类型
print(type(True)) #<class 'bool'>
print(type(str(True))) #<class 'str'>
4、将str类型转换为str类型
print(type("jzq")) #<class 'str'>
print(type(str("jzq"))) #<class 'str'>
5、将tuple类型转化为str类型
print(type((1,2,3))) #<class 'tuple'>
print(type(str((1,2,3)))) #<class 'str'>
6、将list类型转化为str类型
print(type([1,2,3])) #<class 'list'>
print(type(str([1,2,3]))) #<class 'str'>
7、将set类型转换为str类型
print(type({1,2,3})) #<class 'set'>
print(type(str({1,2,3}))) #<class 'str'>
8、将dict类型转化为str类型
print(type({1:"one",2:"two"})) #<class 'dict'>
print(type(str({1:"one",2:"two"}))) #<class 'str'>
九、类似于java中的StringBuilder类
Python 中有类似于 Java 中的 StringBuilder
和 StringBuffer
的概念,但它们的实现和使用方式有些不同。在 Python 中,字符串是不可变的,这意味着一旦创建了字符串,就不能直接修改其内容。然而,Python 提供了一种叫做 io.StringIO
的模块,以及使用列表来构建字符串的方法,类似于 StringBuilder
和 StringBuffer
的功能。
- 使用
io.StringIO
模块:io.StringIO
是一个用于在内存中操作字符串的类。您可以将其看作是一个缓冲区,可以像文件一样写入和读取内容。
import io
string_io = io.StringIO()
string_io.write("Hello")
string_io.write(" World")
result = string_io.getvalue()
print(result) # 输出: "Hello World"
使用列表和 .join()
方法:由于列表是可变的,您可以在列表中构建字符串内容,然后使用 .join()
方法将列表中的元素连接成一个字符串。
string_list = []
string_list.append("Hello")
string_list.append(" World")
result = ''.join(string_list)
print(result) # 输出: "Hello World"
这两种方法都可以用来构建字符串,类似于 StringBuilder
和 StringBuffer
在 Java 中的功能。需要注意的是,io.StringIO
更灵活,允许您进行更多的文件类操作,而使用列表和 .join()
则更简洁。
另外,尽管 Python 的字符串是不可变的,但由于 Python 的内存管理机制,适度的字符串拼接操作通常不会导致性能问题。
希望这个解释能够帮助您理解 Python 中类似于 StringBuilder
和 StringBuffer
的概念和实现。如果您有更多问题,请随时提问。