代码学习笔记

一、继承

在面向对象编程中,继承是一种重要的机制,用于在已有类(父类或基类)的基础上创建新类(子类或派生类)。继承是将父类的东西拿过来用,具体同时可以根据自身需求添加新的属性和方法或重写父类的方法,因此可以不用在自己类上再重新写一遍父类里面有的东西解释如下:

1. 代码复用

继承允许FedAlt类避免重复编写PartialPFLBase类中已经实现的代码,从而减少代码量,提高开发效率。例如,如果PartialPFLBase类已经实现了一些通用的联邦学习相关功能,如数据加载、模型初始化、基本的优化器设置等,FedAlt类无需重新实现这些功能,直接继承即可使用。

2. 功能扩展

FedAlt类可以在继承的基础上添加特定于其算法的新功能。例如,FedAlt类可能实现了交替更新客户端和服务器参数的独特逻辑,这是在PartialPFLBase类的基础上扩展的功能,以满足FedAlt算法的需求。

3. 一致性和标准化

通过继承,FedAlt类遵循了PartialPFLBase类所定义的接口和行为规范,使得整个代码库在联邦学习相关操作上具有一致性和标准化。这有助于其他开发人员更容易理解和使用FedAlt类,因为他们可以基于对PartialPFLBase类的了解来预期FedAlt类的行为。

4. 多态性支持

继承为多态性奠定了基础,多态性使得可以使用父类类型的变量来引用子类对象,并根据对象的实际类型调用相应的重写方法。在联邦学习框架中,这意味着可以编写更通用的代码来处理不同类型的联邦学习算法(如FedAlt和其他可能的子类),只要它们都继承自PartialPFLBase类,就可以以统一的方式进行调用和管理,增强了代码的灵活性和可扩展性。

5. 维护和升级便利性

如果需要对联邦学习的基本功能进行修改或升级(例如,改进数据加载机制或优化器设置),只需在PartialPFLBase类中进行更改,而FedAlt类以及其他继承自该类的子类将自动受益于这些改进,无需在每个子类中单独进行修改,降低了维护成本和出错的可能性。

6.继承与父类成员访问权限

  • 公有成员(public):子类可以毫无限制地访问和使用它们,就如同这些成员是子类自己定义的一样。这意味着子类可以直接调用父类的公有方法来执行特定的操作,并且可以读取和修改父类的公有属性。例如,父类中有一个公有方法calculate_area用于计算图形面积,子类继承后可以直接调用这个方法来获取面积值,也可以根据需要在子类的其他方法中使用这个计算结果。
  • 保护成员(protected):父类的保护成员在子类中是可见的,并且可以被访问和使用,但只能在子类内部进行访问,不能从子类外部直接访问。这为子类提供了一种特殊的访问级别,使得子类能够在继承父类的基础上,对这些保护成员进行适当的操作和扩展,同时又限制了外部对这些成员的随意访问,保护了类的内部结构。例如,父类可能有一个保护属性_radius用于表示圆形的半径,子类在继承后可以在自己的方法中访问和使用这个属性来计算圆的周长或面积,但外部代码无法直接访问_radius属性。(外部代码是指在类定义之外的其他代码部分,它不属于任何一个特定的类内部实现。)
  • 私有成员(private):父类的私有成员对子类是不可见的,子类不能直接访问父类的私有属性和方法。这是为了确保类的内部实现细节完全封装在类内部,防止子类意外地破坏父类的内部状态或行为。即使子类继承了父类,也不能直接获取或修改父类的私有成员。例如,父类可能有一个私有方法_private_method用于内部数据的处理,子类无法直接调用这个方法

7.注意事项

  • 谨慎使用继承关系:虽然继承提供了强大的功能,但不应过度使用。在某些情况下,如果仅仅为了复用少量代码而创建复杂的继承关系,可能会导致代码结构变得复杂难以理解,增加维护成本。例如,如果两个类之间只有部分功能相似,可能使用组合或委托等方式更为合适,而不是直接继承。
  • 方法重写的一致性:当子类重写父类方法时,必须确保重写后的方法在语义和功能上与父类方法保持一致,遵循里氏替换原则(Liskov Substitution Principle)。这意味着子类对象在任何使用父类对象的地方都能够正确替换父类对象,并且程序的行为应该符合预期。否则,可能会导致程序出现难以调试的错误。例如,如果父类的draw方法用于绘制图形的轮廓,子类重写该方法时不能改变其基本功能,而只能在绘制轮廓的基础上添加其他细节或效果。
  • 继承层次的深度控制:避免创建过深的继承层次结构,因为这会使代码的可读性和可维护性变差。当继承层次过多时,追踪代码的执行流程和理解类之间的关系会变得非常困难,尤其是在调试和修改代码时。一般来说,尽量保持继承层次较浅,通常不超过三到四层为宜。如果发现继承层次过深,可以考虑重新设计类结构,采用接口、组合等方式来优化代码组织。

二、self

self的主要作用就是让类中的方法知道它们是在操作属于这个类的某个特定对象(实例)的数据和行为,而不是其他对象的。即self在某种程度上相当于 “自己”,它代表的是类的当前实例对象本身。当使用self.name时,指当前这个实例对象所拥有的名为name的变量(属性)。

在 Python 类的方法中,self是一个约定俗成的参数名,用于指代类的实例对象本身。它在类的方法中具有重要作用,主要体现在以下几个方面:

1. 访问实例属性

类的实例通常具有一些属性,这些属性存储了与该实例相关的数据。通过self,可以在类的方法中访问和操作这些实例属性。例如,如果一个类有一个名为name的实例属性,在类的方法中可以使用self.name来获取或修改该属性的值。

2. 调用实例方法

类的实例方法可以通过self来调用其他实例方法。这使得在一个方法中可以方便地复用其他方法的功能,增强代码的模块化和可维护性。例如,如果一个类有method_amethod_b两个实例方法,在method_a中可以使用self.method_b()来调用method_b

3. 区分实例变量和局部变量

在类的方法中,如果定义了一个与实例属性同名的局部变量,self可以明确指示要访问的是实例属性而不是局部变量。这有助于避免命名冲突,并确保正确地操作实例相关的数据。

4. 实现对象状态的维护

每个实例对象都有其独立的状态,通过self可以在不同的方法调用之间维护和更新这个状态。例如,一个计数器属性可以在一个方法中递增,然后在另一个方法中使用递增后的计数值,这都是通过self来实现的。

5. 作为对象的标识

在一些情况下,self可以作为对象的唯一标识,用于在类的内部逻辑中区分不同的实例。例如,在处理多个对象之间的交互或比较时,self可以帮助确定当前操作涉及的是哪个具体对象。

总的来说,self是 Python 类中实现面向对象编程的关键机制之一,它使得类的实例能够拥有自己独立的状态和行为,并能够在类的方法中方便地访问和操作与实例相关的信息。

三、args,*args,**kwargs

首先,不是必须写成*args和**kwargs,只有变量前面星号*才是必须的。也可以写成*vars和**kwvars,写成*args和**kwargs只是一个通俗的命名约定。

    args: args 是一个常规的参数列表,表示函数接收的位置参数,可以包含零个或多个参数,由逗号分隔。即一个args表示一个参数
    *args: *args 是一个特殊的参数,用于接收任意数量的位置参数,并将它们作为一个元组传递给函数。在函数定义时,可以使用 *args 来接收多个不定长的位置参数,然后对它们进行处理。在调用函数时,可以使用 * 运算符将一个可迭代对象解包成多个单独的参数,然后将它们传递给函数。*args表示的是一个任意长度的元组,即预先并不知道,函数调用时会传递多少个参数。
    **kwargs: **kwargs 是另一个特殊的参数,用于接收任意数量的关键字参数,并将它们作为一个字典传递给函数。在函数定义时,可以使用 **kwargs 来接收多个不定长的关键字参数,然后对它们进行处理。在调用函数时,可以使用 ** 运算符将一个字典解包成多个单独的关键字参数,然后将它们传递给函数。 *kwargs传入的是一个任意长度的字典,即预先并不知道,函数调用时会传递多少个参数。
原文链接:https://blog.youkuaiyun.com/weixin_41862755/article/details/130413872

 四、.to(device)

为了充分利用不同设备的优势,我们需要根据实际情况将模型、数据等安排在合适的设备上进行操作。.to(device)方法提供了一种便捷的方式来实现设备间的迁移。 

device参数的含义

  • device通常是一个表示设备的对象或字符串。在 PyTorch 中,常见的取值有:
    • 'cpu':表示将数据或模型移动到 CPU 上进行处理。这是默认的设备,如果没有特殊要求或者硬件不支持 GPU 加速等情况,数据和模型默认就在 CPU 上操作。
    • 'cuda''cuda:0''cuda:1'等类似形式:'cuda'表示使用默认的可用 CUDA 设备(CUDA 是 NVIDIA 推出的用于 GPU 编程的平台和 API,通常与 NVIDIA 的 GPU 配合使用)。而'cuda:0''cuda:1'等则明确指定使用第几个 CUDA 设备。例如,当你的计算机安装了多个 NVIDIA GPU 时,可以通过这种方式选择具体使用哪一个 GPU 来进行计算。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
img = img.to(device)

  四、Adam优化器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值