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'))
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐