目录
1、Object类
2、初始化方法
3、双下划线方法
4、传递参数
5、装饰器
6、assert
7、yield关键字
1、Object类
class NodeBase(object):
- 在Python中,Object是所有其他类的基类。换句话说,所有的类都是Object类的子类。Object类定义了所有对象的基本行为和属性。
- Object类定义了以下的一些方法:
- init: 这是一个特殊的方法,在创建新对象时自动调用。它是用来初始化新创建的对象的状态的。
- del: 这是一个特殊的方法,当一个对象被垃圾收集器回收时自动调用。它通常用于清理资源,如关闭文件或网络连接。
- str 和 repr: 这两个方法都用于返回对象的字符串表示。它们的主要区别在于,如果可能,str()应该返回一个人类可读的字符串,而repr()应该返回一个可以用来复现该对象的字符串。
- eq 和 ne: 这两个方法用于比较两个对象是否相等。它们的行为由类的实现决定。
- lt, le, gt, ge: 这些方法用于比较两个对象。它们的行为由类的实现决定。
- call: 这是一个特殊的方法,可以在对象上调用。它通常用于模拟函数调用。
- hash: 这个方法返回一个整数,该整数可以被用作哈希值。它通常由不可变类型(如整数、浮点数、字符串和元组)的实现覆写。
- bool: 这个方法返回一个布尔值,该值表示对象是否被视为真值。它通常由有意义的值(如非零的数字或非空的字符串或列表)的实现覆写。
2、初始化方法
def __init__(self,*coord):self.init_coord(*coord)self._ID = Noneself._nAk = Noneself._nBk = Noneself.init_keys()
def __init__(self,*coord)
: 这是类的初始化方法,当你创建这个类的一个实例时,这个方法会被调用。self
是对实例自身的引用,*coord
是一个可变参数,可以接收任意数量的参数。self.init_coord(*coord)
: 这行代码调用了一个名为init_coord
的方法,并将*coord
参数传递给它。这可能是用来初始化坐标或其他相关数据的。self._ID = None
: 这行代码为实例的_ID
属性赋值为None
。这是一个私有属性,以单下划线前缀表示。self._nAk = None
和self._nBk = None
: 这两行代码分别为实例的_nAk
和_nBk
属性赋值为None
。这两个也是私有属性。self.init_keys()
: 这行代码调用了一个名为init_keys
的方法,可能是用来初始化键或相关数据的。
在Python中,*coord
和 **coord
都是在函数参数中使用的,表示对参数进行解包。
-
*coord
是用于解包列表或元组。当你传递一个列表或元组给一个函数,并且使用*
前缀,Python会把这个列表或元组解包为单独的参数。例如:
def sum_numbers(*coord): return sum(coord) numbers = [1, 2, 3, 4, 5]
result = sum_numbers(*numbers) # 这等价于 sum_numbers(1, 2, 3, 4, 5)
print(result) # 输出:15
-
**coord
是用于解包字典。当你传递一个字典给一个函数,并且使用**
前缀,Python会把这个字典解包为单独的关键字参数。例如:
def print_dict(**coord): print(coord) my_dict = {"name": "Alice", "age": 25}
print_dict(**my_dict) # 这等价于 print_dict(name="Alice", age=25)
3、双下划线方法
def __repr__(self):return "Node:%r"%(self.coord,)def __getitem__(self,key):return self.coord[key]
在Python中,双下划线开头的函数(如__repr__
)被称为特殊方法或双下划线方法。这些方法在Python中具有特殊的意义和用途。__repr__
方法就是其中之一。
__repr__
是一个内置方法,用于返回一个对象的字符串表示。这个方法的目的是让对象可以被准确地、无歧义地重新创建。通常,__repr__
应该返回一个字符串,这个字符串包含了一个可以用来复制对象的Python表达式。
例如,如果你有一个名为Person
的类,它有一些属性如name
和age
,你可以这样定义__repr__
方法:
class Person: def __init__(self, name, age): self.name = name self.age = age def __repr__(self): return f"Person('{self.name}', {self.age})"
person = Person('Alice', 25)
print(person) # 输出:Person('Alice', 25)
4、传递参数
def init_coord(self,*coord):self._x = 0.self._y = 0.self._z = 0.if len(coord) == 1:self.dim = len(coord[0])if self.dim == 2:self._x = coord[0][0]*1.self._y = coord[0][1]*1.self.coord = (self.x,self.y)elif self.dim == 3:self._x = coord[0][0]*1.self._y = coord[0][1]*1.self._z = coord[0][2]*1.self.coord = (self.x,self.y,self.z)else:raise AttributeError("Node dimension is 2 or 3")elif len(coord) == 2:self.coord = tuple(coord)self.dim = 2self._x = coord[0]*1.self._y = coord[1]*1.self.coord = (self.x,self.y)elif len(coord) == 3:self.coord = tuple(coord)self.dim = 3self._x = coord[0]*1.self._y = coord[1]*1.self._z = coord[2]*1.self.coord = (self.x,self.y,self.z)else:raise AttributeError("Node dimension is 2 or 3")
这段代码是定义了一个对象的三个私有属性:_x, _y, _z,并设置了对象的一个公有属性coord。方法接收一个或多个参数,并根据参数的数量和类型设置属性的值,可以是列表list、元组tuple或numpy.ndarray类型。
5、装饰器
@propertydef nBk(self):return self._nBk
@property
:这是一个装饰器的语法,用于将下面的方法标记为一个属性。这意味着该方法可以在类实例上使用点表示法(即obj.nBk)来访问。def nBk(self):
:这是一个名为nBk
的方法,它是一个属性的定义。该方法没有参数,并且返回一个值,这个值是通过return self._nBk
得到的。return self._nBk
:这个语句返回self._nBk
的值。在这里,self._nBk
应该是该类的一个实例属性(即在实例创建时赋值的属性),它存储了真正的值。由于nBk
方法是一个只读属性,所以它没有参数,并且不接受任何输入参数。
@x.setterdef x(self,val):self._x = val
@x.setter
:这是一个装饰器语法,用于定义一个名为x
的setter方法。setter方法是用于设置对象属性的方法。在Python中,setter方法通常用于当您想要在更改属性的值时执行一些额外的操作,例如验证或记录日志。def x(self, val):
:这是定义的setter方法。它的名称是“x”,它是一个实例方法(因为它以self
为第一个参数),并且它接受一个额外的参数val
,这是我们要设置的新值。self._x = val
:这行代码是将新的值赋给属性_x
。在Python中,通常使用下划线前缀来表示一个变量的名称是私有的,这意味着它应该在类的外部被隐藏,并且只能通过类内部的方法来访问。在这里,我们假设_x
是这个类的私有属性,所以我们使用下划线前缀。
class Person: def __init__(self, ID): self._ID = ID @ID.setter def ID(self, val): self._ID = val
p = Person(123)
p.ID = 456 # 这里调用了setter方法,将_ID属性的值更改为456
print(p._ID) # 输出:456
6、assert
assert boolean_expression
assert
boolean_expression,
message
assert issubclass(type(nd),NodeBase),"Must be Node type"
这段代码是在一个类的初始化方法__init__
中使用了一个断言语句assert
。断言语句用于在运行时检查代码的正确性,如果条件不满足,则会引发一个异常。
在这段代码中,assert issubclass(type(nd),NodeBase),"Must be Node type"
这行代码的含义是检查变量nd
是否是NodeBase
类或其子类的实例。如果不是,它将引发一个异常,异常信息为"Must be Node type"。
具体来说,type(nd)
会返回变量nd
的类型,issubclass(type(nd),NodeBase)
会检查返回的类型是否是NodeBase
类或其子类。如果是,返回True;否则返回False。如果issubclass
返回False,即nd
不是NodeBase
类或其子类的实例,那么assert
语句就会引发一个异常,异常信息为"Must be Node type"。
这种断言方式常常用于确保程序的正确性,避免程序在运行时出现不可预期的行为。
def zeros(s):a=int(s)assert a>0,"out range"return a
print(zeros(-1))
7、yield关键字
yield在函数中的功能类似于return,不同的是yield每次返回结果之后函数并没有退出,而是 每次遇到yield关键字后返回相应结果,并保留函数当前的运行状态,等待下一次的调用。如果 一个函数需要多次循环执行一个动作,并且每次执行的结果都是需要的,这种场景很适合使用yield实现。
包含yield的函数成为一个生成器,生成器同时也是一个迭代器,支持通过next方法获取下一个值。
使用yield的好处是通过使用生成器,避免占用内存,提高运行效率。
def pair_wise(L,end = False):pool = tuple(L)n = len(pool)assert n >=2,"Length of iterable must greater than 3" if end is True:indices = list(range(n))for i in indices:if i < n -1:yield (pool[i],pool[i+1])else:yield (pool[i],pool[0])if end is False:indices = list(range(n-1))for i in indices:yield (pool[i],pool[i+1])
a=[1,2,3,4]
for i in pair_wise(a,True):print(i)
(1, 2)
(2, 3)
(3, 4)
(4, 1)