Python中类的理解
1. what is class?
当我们需要创造一个object(定义+对其执行操作)时,在代码内部构造class会更加方便。
可以理解为class是做饼干的模具,而调用class就是做出了一个一个饼干。
因为每次放入的面粉不同(比如有黄油的,有抹茶的),所以每个饼干不同,但是他们的样子都是和模具一样的。
类的定义方法
class user():
def __inti__(self, username, name, email):
self.name = name
self.username = username
self.email = email
def __repr__(self):
return f"the username is '{self.username}'"
def __str__(self):
return self.__repr__()
在这个例子里面,创建了一个名为User的类。
包含了定义类需要的几个要素:
1,类需要的属性(attributes)------>(name, username, email)
def __init__(self, username, name, email): # 函数需要传入的参数
self.username = username
# self.username的username是我们创建的user类包含的属性,
# 也可以写成 self.username111 = username
# 前者是类定义时自带的属性,后者是调用类创建object的时候传入的参数
self.name = name
self.email = email
对于self,(self.xxx 是对象属性)着重阐述一下:
user1 = user('olivia', 'olivia_shy', 'olivia@gamil.com')
当执行以上这段代码时,发生了如下3件事:
1. python创建了一个空对象
2. 将这个空的user对象传入__inti__()
3. 在__inti__()里面执行 (此时self就是user1):
# 因为user这个类自带name, username, email属性
self.name = 'olivia'
self.username = 'olivia_shy'
self 自动带有 __init__ 中定义的属性,
因为那些属性就是绑定在这个对象(self)上的数据。而这些属性的值(比如传入的参数)会在对象创建时通过 __init__ 保留下来。
summary:
| 情况 | 是否用 self |
|---|---|
|
需要 在整个对象中共享、保留状态(跨方法访问) 一般是在inti中定义的属性可以在当前类的函数中使用self.xxx |
✅ 用 self.xxx |
| 只在当前函数临时使用 | ❌ 不用 self,直接写局部变量即可 |
标准写法:
class ClassName:
def __init__(self, 参数1, 参数2, ...):
self.属性1 = 参数1
self.属性2 = 参数2
2,对类执行的操作(methods)-------> ( __repr__() &&__str__() )
def __repr__(self):
return (f'User(username = "{self.username}"')
# 这里的self指代object本身,当调用class user之后,会创建一个object
method是基于__inti__()传入的参数写的
3, __init__函数
__inti__()函数可写可不写,但大多情况下都需要写。
比如
1.需要定义一些类的特征(如上user类)
2.需要初始化一些变量
class email():
domain = 'gmail.com'
def __inti__(self, username):
self.email = username + domain
3. 在创建时进行检查
class User:
def __init__(self, username, email):
if "@" not in email:
raise ValueError("邮箱格式错误")
self.username = username
self.email = email
4. 预先准备一些数据结构
class UserDataBase():
def __init__(self):
self.users = list()
2. 类中method的写法
以以下代码为例
class UserDataBase():
def __init__(self):
self.users = list()
# assume lst is in increasing order
def binary(self, lst, element):
low, high = 0, len(lst) - 1
while low <= high:
mid = low + (high - low) // 2
if lst[mid].username == element.username:
return mid
elif lst[mid].username > element.username:
high = mid - 1
else:
low = mid + 1
return low
def insert(self, user):
loc = self.binary(self.users, user)
self.users.insert(loc, user)
def find(self, username):
for user in self.users:
if user.username == username:
return user
return None
def update(self, user):
target = self.find(user.username)
if target:
target.name, target.email = user.name, user.email
else:
raise ValueError(f"User '{user.username}' not found")
def list_(self):
return self.users
结构
创建了一个userdatabase的类。
自带属性是一个名为users的列表 [ user(), user(), user(), ......]
┌────────────────────────────┐
│ UserDataBase 类 │
│────────────────────────────│
│ 属性: │
│ self.users → 一个 list │
│ │
│ 方法: │
│ insert(self, user) │ ← 你自己定义的逻辑函数
│ find(self, username) │
│ update(self, user) │
│────────────────────────────│
│ 内部调用: │
│ self.users.insert(...) │ ← 调用 Python 内置 list 的方法
└────────────────────────────┘
对于binary函数,就是一个简单的二分插入,如果不理解可以忽略.
作用是找到insert()传入的user插入的位置。
对于内部函数or外部函数的问题:
这个函数是否依赖类的内部状态(self)?
-
如果 是 → 应该写在类里面(作为方法)。
-
如果 否 → 可以写在类外面(作为独立函数)。
| example | 推荐写法 |
|---|---|
| 这个算法只为这个类服务(例如专门找用户名) | 放在类内(可用 binary) |
| 这个算法比较通用(可以用于很多不同列表) | 放在类外,做通用函数 |
调用类实例的结构
db = UserDatabase()
UserDatabase 类
└── 实例对象 db (就是 self)
└── 属性 users(列表)
└── 元素 user(是 User 类的实例)
├── username
└── email
需要注意如果执行 db.insert()
在self.users.insert(loc, user)这行
self.users 是一个列表,不存在 .username 属性。
eg:
db.insert(user('harry', 'harrystyles'))更多推荐



所有评论(0)