1、类
类是一种抽象概念,它是用来创建对象的蓝图。它定义了对象拥有的属性和方法。对象是类的实例,它是类的具体实现。
定义类
类定义语法:
class 类名:
类变量
方法定义
class Person:
x = 10 # 类变量
def __init__(self, name, age): # 构造函数
self.name = name # 实例变量
self.age = age
def say_hello(self): # 方法
print("这是方法")
2、对象
对象是类的实例化,是类的实际数据存储,具有类所定义的属性和方法。
变量 = 类名([参数])
说明
变量存储的是实例化后的对象地址
类参数按照初始化方法的形参传递
对象是类的实例,具有类定义的属性和方法。
通过调用类的构造函数来创建对象。
每个对象有自己的状态,但共享方法。
# 类定义:
class Person: #Person是一个类
x = 10 # 类变量
def __init__(self, name, age): # 构造函数
self.name = name # 实例变量
self.age = age
def say_hello(self): # 方法
print("这是方法")
# 实例化对象:
p1 = Person("张三", 20) #p1就是另一个对象
p2 = Person("李四", 22) #p2就是另一个对象
print(p1.x,id(p1.x)) # 10
print(p1.name,id(p1.name)) # 张三
print(p1.age,id(p1.age)) # 20
p1.say_hello() # 这是方法
print(p2.x,id(p2.x)) # 10, 实例变量的地址是不一样的
print(p2.name,id(p2.name)) # 李四
print(p2.age,id(p2.age)) # 22
3、属性和方法
3.1实例属性
# 类定义:
class Person:
x = 10 # 类变量
def __init__(self, name, age): # 构造函数
self.name = name # 实例变量
self.age = age
def say_hello(self): # 方法
print("这是方法")
p1 = Person("张三", 20) # 实例化对象
print(p1.x) # 访问类变量
p1.y = 20 # 添加实例变量
print(p1.y) # 访问类变量
3.2实例方法
# 类定义:
class Person:
def f(self, food): # 方法
print("我喜欢吃" + food)
def f1(self, food):
print("我不喜欢吃" + food)
def f2(self, food):
print("我爱吃" + food)
def f3(self):
print("我是一个人")
def f4(a): # 这里的a应该写成self,只是为了演示参数名可以任意,但一般习惯用self作为接收对象本身的参数名。
print("我是一个好人")
# 实例化对象:
p1 = Person()
p1.f1("苹果")
p1.f2("香蕉")
p1.f3()
p1.f4()
#在调用方法时,会自动将对象作为第一个参数传入。
#p1.f3() 等价于 p1.f3(p1)
#所以,在定义方法时,必须要有参数来接收对象。
#所以,在定义方法时,第一个参数接收的是对象本身。
#如 def f4(a): 这里的 a 就是对象本身。
#接收对象本的参数名可以随意取名,但一般习惯用 self 作为参数名。
3.3类属性
-
类属性是类的属性,此属性属于类,不属于此类的实例
-
作用:
-
通常用来存储该类创建的对象的共有属性
-
-
类属性说明
-
类属性,可以通过该类直接访问
-
类属性,可以通过类的实例直接访问
-
# 类属性
# 类属性是指类本身的属性,它属于类本身,而不是对象。
# 类属性可以通过类名来访问,而不是对象。
# 类属性可以通过类名.属性名来访问。
# 类属性可以通过类名.属性名 = 值 来设置值。
class Person:
name = "人类" # 类属性
x = 10 # 类属性
def __init__(self, name): # 构造方法
self.name = name # 对象属性
print(Person.name) # 访问类属性;输出:人类
p1 = Person("小明") # 实例化对象
print(p1.name) # 访问对象属性;输出:小明
Person.name = "动物" # 修改类属性的值
print(Person.name) # 输出:动物
print(p1.name) # 输出:小明,对象属性的值没有变化
print(Person.x) # 输出:10
print(p1.x) # 输出:10,对象属性的值没有变化
p1.x = 20 # 给对象属性赋值
print(Person.x) # 输出:10,类属性的值没有变化
print(p1.x) # 输出:20,对象属性的值发生变化
Person.x = 30 # 修改类属性的值
print(Person.x) # 输出:30
print(p1.x) # 输出:20,对象属性的值没有变化
#实例化对象以后,类属性改变,对象属性不变。
#实例化对象以后,对象属性改变,类属性不变。
Person.x = 40 # 修改类属性的值
p2 = Person("小红") # 实例化对象
print(p2.x) # 输出:10,对象属性的值没有变化
#因为p2实例化前,Person类中x的值改变,所以p2的x属性值也为40。
3.4类方法
-类方法是用于描述类的行为的方法,类方法属于类,不属于该类创建的对象
说明
类方法需要使用@classmethod装饰器定义
类方法至少有一个形参用于绑定类,约定为 $cls$
类和该类的实例都可以调用类方法
类方法不能访问此类创建的对象的实例属性
类方法示例1
class A:
v = 0
@classmethod
def set_v(cls, value):
cls.v = value
@classmethod
def get_v(cls):
return cls.v
print(A.get_v())
A.set_v(100)
print(A.get_v())
a = A()
print(a.get_v())
```
类方法示例2
class MyClass:
class_attr = 0 # 类属性
def __init__(self, value):
self.instance_attr = value # 实例属性
@classmethod
def modify_class_attr(cls, new_value):
cls.class_attr = new_value
print(f"类属性已修改为: {cls.class_attr}")
@classmethod
def try_modify_instance_attr(cls):
try:
cls.instance_attr = 10 # 事出反常必有妖
except AttributeError as e:
print(f"错误: {e}")
# 创建类的实例
obj = MyClass(5)
# 调用类方法修改类属性
MyClass.modify_class_attr(20) # 输出: 类属性已修改为: 20
MyClass.try_modify_instance_attr() # 事出反常必有妖
```
3.5 静态方法
-
静态方法定义在类的内部,作用域是类内部
-
说明
-
使用@staticmethod装饰器定义
-
不需要self和cls参数
-
通过类或类实例调用
-
可以访问类属性,不能访问实例属性
-
-
静态方法示例
class A:
class_attr = 42 # 类属性
def __init__(self, value):
self.instance_attr = value # 实例属性
@staticmethod
def myadd(a, b):
# 只能访问传递的参数,不能访问实例属性
return a + b
# 创建类实例
a = A(10)
# 调用静态方法
print(A.myadd(100, 200)) # 输出: 300
print(a.myadd(300, 400)) # 输出: 700
3.6 构造方法
构造方法__new__():
-
负责对象的 创建 和内存分配的。
-
在对象实例化时被调用,负责返回一个新的对象实例。
-
通常不需要显式地定义
__new__()方法,Python会调用基类 object 的__new__()方法。
class MyClass:
def __new__(cls, *args, **kwargs):
print("调用 __new__ 方法,创建对象")
return super().__new__(cls)
def __init__(self, value):
print("调用 __init__ 方法,初始化对象")
self.value = value
# 创建对象
obj = MyClass(10)
3.7 初始化方法
-
一旦对象被创建,Python会调用
__init__()来初始化对象的属性。 -
语法格式:
class 类名(继承列表):
def __init__(self[, 形参列表]):
语句块
# [] 代表其中的内容可省略
接收实参到 __init__方法中
class MyClass:
def __new__(cls, *args, **kwargs):
print("调用 __new__ 方法,创建对象")
return super().__new__(cls)
def __init__(self, value):
print("调用 __init__ 方法,初始化对象")
self.value = value
# 创建对象
obj = MyClass(10)
3.8魔术方法
魔术方法是一种特殊的方法,用双下划线包裹,例如__init__,__str__,__add__等。这些方法允许您自定义类的行为,以便与内置Python功能(如+运算符、迭代、字符串表示等)交互。
3.8.1常用方法
-
__init__(self, ...): 初始化对象,通常用于设置对象的属性。 -
__str__(self): 定义对象的字符串表示形式,可通过str(object)或print(object)调用。例如,您可以返回一个字符串,描述对象的属性。 -
__repr__(self): 定义对象的“官方”字符串表示形式,通常用于调试。可通过repr(object)调用。 -
__len__(self): 定义对象的长度,可通过len(object)调用。通常在自定义容器类中使用。 -
__getitem__(self, key): 定义对象的索引操作,使对象可被像列表或字典一样索引。例如,object[key]。 -
__setitem__(self, key, value): 定义对象的赋值操作,使对象可像列表或字典一样赋值。例如,object[key] = value。 -
__delitem__(self, key): 定义对象的删除操作,使对象可像列表或字典一样删除元素。例如,del object[key]。 -
__iter__(self): 定义迭代器,使对象可迭代,可用于for循环。 -
__next__(self): 定义迭代器的下一个元素,通常与__iter__一起使用。 -
__add__(self, other): 定义对象相加的行为,使对象可以使用+运算符相加。例如,object1 + object2。 -
__sub__(self, other): 定义对象相减的行为,使对象可以使用-运算符相减。 -
__eq__(self, other): 定义对象相等性的行为,使对象可以使用==运算符比较。 -
__lt__(self, other): 定义对象小于其他对象的行为,使对象可以使用<运算符比较。 -
__gt__(self, other): 定义对象大于其他对象的行为,使对象可以使用>运算符比较。 -
__call__(self, other)是一个特殊的方法(也称为“魔法方法”),它允许一个对象像函数一样被调用。
3.8.2 案例参考
1.__str__():定义 print() 或 str() 函数调用时的输出字符串表示。
__str__() 方法用来定义当你调用 print() 或 str() 时对象应该返回的字符串。
该方法必须返回一个字符串,通常用于给用户可读的对象描述。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person: {self.name}, Age: {self.age}"
p = Person("Alice", 30)
print(p) # 输出: Person: Alice, Age: 30
作用:
使得你的对象在打印时更加友好和可读。
提供更好的调试输出。
2.__repr__():定义 repr() 函数的输出,通常用于开发和调试,给出对象的正式字符串表示。
示例:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person('{self.name}', {self.age})"
p = Person("Alice", 30)
print(repr(p)) # 输出: Person('Alice', 30)
作用:
__repr__() 方法用于返回一个可以用来重新创建对象的字符串,理想情况下,返回的字符串应当是合法的 Python 表达式。
如果你没有定义 __str__(),那么 __repr__() 会被用来替代 str() 和 print()。
__repr__() 是供开发人员使用的,输出的字符串应该尽可能接近于可以创建该对象的代码。
在调试时使用 repr() 更加方便,它提供了一个清晰的对象表示。
3.__add__():定义 + 运算符的行为。
示例:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Point({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3) # 输出: Point(4, 6)
作用:
该方法允许你重载加法操作符 +,使其在两个对象之间执行加法时能够自定义行为。
允许你自定义 + 运算符的行为。
4.__len__():定义 len() 函数的行为。
示例:
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3])
print(len(my_list)) # 输出: 3
作用:
__len__() 方法允许你自定义 len() 函数的行为,返回对象的长度。
使得你的对象能够与 len() 函数兼容,返回对象的长度。
5.__getitem__():定义对象支持索引([])操作。
示例:
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4])
print(my_list[2]) # 输出: 3
作用:
__getitem__() 方法使得对象能够支持类似列表、元组那样的索引操作。
使对象能够支持索引操作,类似于内置的数据结构(如列表、字典)。
6.__setitem__():定义对象支持索引赋值操作([] =)。
示例:
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([1, 2, 3])
my_list[1] = 10
print(my_list.items) # 输出: [1, 10, 3]
作用:
__setitem__() 方法允许你定义如何通过索引给对象赋值。
使对象能够支持索引赋值操作。
7.__del__():定义对象的析构方法,通常用于资源清理。
示例:
class MyClass:
def __init__(self, name):
self.name = name
print(f"对象 {name} 创建")
def __del__(self):
print(f"对象 {self.name} 被销毁")
obj = MyClass("Test")
del obj # 输出: 对象 Test 被销毁
作用:
这个方法在对象销毁时调用,通常用于清理资源(如关闭文件、数据库连接等)。
用于对象销毁时进行资源清理。
8.__eq__():定义 == 运算符的行为。
示例:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # 输出: True
作用:
该方法允许你自定义对象的相等比较行为,默认情况下,Python 会比较对象的内存地址。
使你能够自定义如何比较对象的相等性。
3168

被折叠的 条评论
为什么被折叠?



