0起因
最近,在刷题的过程中思考如何把代码的向量命名规范化,进一步的希望规范化完整的代码功能和设计模式。
以 leetcode第3题:https://leetcode.cn/problems/longest-substring-without-repeating-characters/为例。
正常代码为:
1 | class Solution: |
这是通常的LeetCode格式,没有问题。
但是,如果想定义一个构造函数__init__
初始化向量那应该怎么做呢?
于是,按照逻辑和想法写了一下。
1 | class Solution: |
写完之后,诞生一个新的问题:能不能把 n
这个长度向量也放在初始化中呢?
答案是不行,更应该说是“不规范”。
1以下类型的变量放在__init__
__init__
方法(构造函数)用于初始化一个类的实例的状态。
因此,你应该把以下类型的变量放在 __init__
中:
属于对象本身的属性 (Attributes that belong to the object itself):
这些变量描述了对象的特征或状态,并且在对象的整个生命周期内都可能被使用。
它们对于每个对象实例来说可能是不同的。
例子:
1
2
3
4
5
6
7
8
9class Dog:
def __init__(self, name, breed, age):
self.name = name # 属于狗的名字
self.breed = breed # 属于狗的品种
self.age = age # 属于狗的年龄
my_dog = Dog("Buddy", "Golden Retriever", 3)
your_dog = Dog("Lucy", "Labrador", 5)
# my_dog 和 your_dog 有不同的 name, breed, age
对象创建时必须提供的参数 (Parameters required when creating the object):
- 这些参数是创建对象时不可或缺的,用于设置对象的初始状态。
- 它们通常被用来初始化对象的属性。
- 例子(和上面一样):
name
,breed
,age
是创建Dog
对象时必须提供的。
对象内部使用的,但不需要外部直接访问的变量 (Variables used internally by the object, but not directly accessed externally):
这些变量通常用于存储对象的内部状态,或者作为对象方法的辅助变量。
它们通常以下划线
_
开头(例如self._internal_counter
),这是一种约定,表示它们是“私有的”或“受保护的”,不建议从对象外部直接访问。例子:
1
2
3
4
5
6
7class Circle:
def __init__(self, radius):
self.radius = radius
self._area = 3.14159 * radius * radius # 内部计算的面积,不直接暴露
def get_area(self): # 提供一个方法来获取面积
return self._area
与对象关联的其他对象 (Other objects associated with the object):
如果一个对象需要与其他对象协作,那么这些其他对象的引用可以作为属性存储在
__init__
中。 这体现了对象之间的“has-a”关系(组合或聚合)。例子:
1
2
3
4
5
6
7
8
9
10
11
12class Engine:
def __init__(self, horsepower):
self.horsepower = horsepower
class Car:
def __init__(self, make, model, engine):
self.make = make
self.model = model
self.engine = engine # Car "has-a" Engine
my_engine = Engine(200)
my_car = Car("Toyota", "Camry", my_engine)
默认值属性 (Attributes with default values):
如果某些属性在对象创建时可以不提供,你可以给它们设置默认值。
例子:
1
2
3
4
5
6
7class Rectangle:
def __init__(self, width, height=1): # height 有默认值 1
self.width = width
self.height = height
rect1 = Rectangle(5) # height 使用默认值 1
rect2 = Rectangle(5, 10) # height 被指定为 10
不应该放在 __init__
中的变量:
局部变量 (Local variables): 只在某个方法内部使用的临时变量,不属于对象的状态,应该在方法内部定义。
与特定方法调用相关的变量 (Variables related to a specific method call): 例如,
lengthOfLongestSubstring
方法中的n
,它是输入字符串s
的长度,与对象本身的状态无关,应该在方法内部计算。类级别的变量 (Class-level variables): 这些变量属于类本身,而不是类的实例。它们应该在类定义中直接定义,而不是在
__init__
中。 类变量在所有实例之间共享。1
2
3
4
5class MyClass:
class_variable = 0 # 类变量
def __init__(self, instance_variable):
self.instance_variable = instance_variable # 实例变量
2总结
__init__
的目的是初始化对象的状态。
变量是否应该放在 __init__
中,取决于它是否是对象持久状态的一部分,或者是否在对象创建时必须提供。
清晰地区分对象的属性(放在 __init__
中)和方法的局部变量(放在方法内部)对于编写清晰、可维护的代码至关重要。
在LeetCode第三题中,n
与特定的调用方法相关而且与对象本身状态无关,应该在方法内部计算。