重写线程类

import threading,time


# 自定义线程类
class MyThread(threading.Thread):
    def __init__(self, num):
        super().__init__() # 要先调用父类的init方法否则会报错
        self.num = num

# 重写 父类run方法
def run(self):
    for i in range(self.num):
        print("正在执行子线程的run方法...",i)
        time.sleep(0.5)

if __name__ == '__main__':
    mythread = MyThread(5)
    mythread.start()
import threading

# 定义一个线程锁对象
file_lock = threading.Lock()

def write_to_file(data):
# 尝试获取线程锁
with file_lock:
# 如果获取成功,则执行文件写入操作
with open('data.txt', 'a') as file:
file.write(data + '\n')



文件线程锁


Python的with语句来自动管理线程锁的获取和释放。with语句会在进入代码块时自动获取锁,当代码块执行完毕后,无论是否发生异常,都会自动释放锁。

这是with语句的一个重要特性,它确保了锁的释放是原子性的,即使在写入文件的过程中发生异常,锁也会被正确释放,从而避免了死锁的情况。

具体来说,with file_lock:这一行代码会尝试获取file_lock对象所代表的锁。如果锁已经被其他线程持有,当前线程将会等待,直到锁被释放。一旦获取到锁,with语句块内的代码就会执行。在with语句块的最后,Python会自动释放锁,使得其他正在等待的线程可以继续执行。

这种机制非常适合处理文件写入等需要保证原子性和一致性的操作,因为它可以确保在写入操作完成之前,不会有其他线程同时对同一文件进行写入,从而避免了数据的混乱和冲突。同时,自动释放锁也减少了程序员在编写并发代码时需要考虑的复杂性,降低了出错的可能性。
继承父类的话可以直接去调用父类里面的通用行为,不用每个函数上面都添加,但是如果不继承的话,每个函数里面都要添加
您提出了一个很好的问题。确实,当我们在父类中增加一个新的行为(方法)后,在子类中创建对象并使用这些行为时,我们需要编写相应的代码来调用这些方法。但是,这样做的好处在于几个方面:

1. **集中管理**:所有通用的行为都在父类中定义,这意味着所有新增或修改的行为只需要在一个地方进行,而不是分散在多个函数中。

2. **减少重复**:虽然在子类中创建对象后调用行为时需要编写代码,但相比不使用继承和重写的情况,我们避免了在多个函数中重复相同的行为实现。

3. **提高可读性**:通过继承和多态性,我们可以编写更通用的代码来处理不同类型的对象,而不需要关心对象的具体类型。

4. **扩展性**:如果需要添加新的行为,只需要在父类中增加相应的方法,而所有子类都自动获得了这个新行为,无需对每个子类进行修改。

为了更清楚地说明这一点,让我们通过一个例子来展示如何在父类中增加新行为,以及如何在子类中使用这些行为:

### 父类增加新行为

```python
class Animal:
def make_sound(self):
raise NotImplementedError("Subclass must implement this method.")
def eat(self):
print("The animal is eating.")
# 可以继续添加更多通用行为,如 sleep, play 等
```

### 子类使用新行为

```python
class Dog(Animal):
def make_sound(self):
print("The dog is barking.")

# 其他子类...

# 创建对象并使用新行为
dog = Dog()
dog.make_sound() # 调用子类特有的行为
dog.eat() # 调用父类中定义的通用行为
```

在这个例子中,我们在 `Animal` 类中定义了 `eat` 方法,所有继承自 `Animal` 的子类都自动拥有了这个方法,无需在每个子类中重复定义。当我们创建 `Dog` 类的实例并调用 `eat` 方法时,我们实际上是在使用在父类中定义的行为。

### 调用行为的代码量

确实,无论是使用函数还是使用类和对象,我们都需要编写代码来调用行为。但是,使用类和对象的好处在于:

- **更好的组织**:所有关于特定类型对象的行为都集中在一个类中,而不是分散在多个函数中。
- **更灵活的扩展**:添加新行为时,只需修改父类,所有子类都自动获得新行为。
- **多态性**:可以使用父类引用来统一处理所有子类对象,编写更通用的代码。

因此,虽然在子类中创建对象并调用行为时确实需要编写代码,但这种做法从整体上减少了代码的重复,提高了代码的组织性、可读性和可维护性。


NotImplementedError 是Python标准异常库中的一个内置异常类型,用于指出某个方法应该由子类实现,但在基类中尚未实现。在这种情况下,make_sound 方法通过 raise NotImplementedError 抛出一个 NotImplementedError 异常,如果代码尝试直接在 Animal 类的实例上调用 make_sound 方法,就会引发异常。






User: 能不能给个形象一点的讲解继承重写类
Kimi: 当然可以!我们可以通过一个形象的比喻来理解类继承和重写。

### 类比:汽车和跑车

想象一下,你有一个汽车制造商,他们生产各种各样的汽车。这些汽车有一些基本的特性和功能,比如发动机、车轮、刹车系统等。这些基本特性和功能可以被看作是一个基类(父类),我们称之为`Car`。

```python
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model

def start_engine(self):
print("Engine started.")

def stop_engine(self):
print("Engine stopped.")
```

在这个基类中,`start_engine`和`stop_engine`是所有汽车都会执行的基本操作。

### 继承:跑车

现在,你想要制造一种更特别的汽车——跑车。跑车拥有汽车的所有特性,但也有一些额外的特性,比如更强大的发动机和更快的速度。跑车可以看作是`Car`的一个子类,我们称之为`SportsCar`。

```python
class SportsCar(Car): # 继承Car类
def __init__(self, brand, model, horsepower):
super().__init__(brand, model) # 调用基类的构造器
self.horsepower = horsepower

def accelerate(self):
print(f"Accelerating with {self.horsepower} horsepower!")
```

在这个子类中,我们首先调用了基类`Car`的构造器(通过`super().__init__(brand, model)`),这样跑车就会拥有品牌和型号这两个属性。然后,我们添加了跑车特有的属性`horsepower`和方法`accelerate`。

### 重写:特殊功能

假设你还想为跑车添加一些特殊功能,比如一个特殊的启动引擎的方式。你可以重写基类中的`start_engine`方法。

```python
class SportsCar(Car):
def __init__(self, brand, model, horsepower):
super().__init__(brand, model)
self.horsepower = horsepower

def start_engine(self): # 重写基类的方法
print("Special sports car engine started with a roar!")

def accelerate(self):
print(f"Accelerating with {self.horsepower} horsepower!")
```

在这里,`start_engine`方法被重写,使得跑车启动引擎时会发出特别的轰鸣声。

### 使用示例

```python
my_car = Car("Toyota", "Corolla")
my_car.start_engine() # 普通的启动引擎

my_sports_car = SportsCar("Ferrari", "F8", 720)
my_sports_car.start_engine() # 跑车的特殊启动引擎
my_sports_car.accelerate() # 跑车的加速
```

在这个示例中,你可以看到:
- `Car`类定义了汽车的基本特性和行为。
- `SportsCar`类继承了`Car`类,并添加了跑车特有的属性和方法。
- `SportsCar`类重写了`start_engine`方法,提供了跑车特有的启动引擎方式。

通过这种方式,你可以很容易地理解和扩展你的类,同时保持代码的清晰和可维护性。

当然 如果你不想继承父类通用函数 那也可以不用写init直接复写就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值