C# 对象作为参数_史上最全 Python 面向对象编程( 五 )


9. iter()
这是迭代器方法!列表、字典、元组之所以可以进行for循环,是因为其内部定义了 iter()这个方法 。如果用户想让自定义的类的对象可以被迭代,那么就需要在类中定义这个方法,并且让该方法的返回值是一个可迭代的对象 。当在代码中利用for循环遍历对象时,就会调用类的这个iter()方法 。
普通的类:
class Foo:passobj = Foo()for i in obj:print(i)# 报错:TypeError: 'Foo' object is not iterable
# 原因是Foo对象不可迭代添加一个__iter__(),但什么都不返回:class Foo:def __iter__(self):passobj = Foo()for i in obj:print(i)# 报错:TypeError: iter() returned non-iterator of type 'NoneType'#原因是 __iter__方法没有返回一个可迭代的对象

返回一个个迭代对象:
class Foo:def __init__(self, sq):self.sq = sqdef __iter__(self):return iter(self.sq)obj = Foo([11,22,33,44])for i in obj:print(i)

C# 对象作为参数_史上最全 Python 面向对象编程

文章插图
最好的方法是使用生成器:
class Foo:def __init__(self):passdef __iter__(self):yield 1yield 2yield 3obj = Foo()for i in obj:print(i)
10、len()
在中,如果你调用内置的len()函数试图获取一个对象的长度,在后台,其实是去调用该对象的len()方法,所以,下面的代码是等价的:
len('ABC')3'ABC'.__len__()3
的list、dict、str等内置数据类型都实现了该方法,但是你自定义的类要实现len方法需要好好设计 。
11. repr()
这个方法的作用和str()很像,两者的区别是str()返回用户看到的字符串,而repr()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的 。通常两者代码一样 。
class Foo:def __init__(self, name):self.name = namedef __str__(self):return "this is %s" % self.name__repr__ = __str__
12. add__: 加运算 _sub_: 减运算 _mul_: 乘运算 _div_: 除运算 _mod_: 求余运算 __pow: 幂运算
这些都是算术运算方法,需要你自己为类设计具体运算代码 。有些内置数据类型,比如int就带有这些方法 。支持运算符的重载,也就是重写 。
class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)v2 = Vector(5,-2)print (v1 + v2)
13. 作者信息
__author__ = "Jack"def show():print(__author__)show()
14. slots
作为一种动态语言,可以在类定义完成和实例化后,给类或者对象继续添加随意个数或者任意类型的变量或方法,这是动态语言的特性 。例如:
def print_doc(self):print("haha")class Foo:passobj1 = Foo()obj2 = Foo()# 动态添加实例变量obj1.name = "jack"obj2.age = 18# 动态的给类添加实例方法Foo.show = print_docobj1.show()obj2.show()
但是!如果我想限制实例可以添加的变量怎么办?可以使slots限制实例的变量,比如,只允许Foo的实例添加name和age属性 。
def print_doc(self):print("haha")class Foo:__slots__ = ("name", "age")passobj1 = Foo()obj2 = Foo()# 动态添加实例变量obj1.name = "jack"obj2.age = 18obj1.sex = "male"# 这一句会弹出错误# 但是无法限制给类添加方法Foo.show = print_docobj1.show()obj2.show()由于'sex'不在__slots__的列表中,所以不能绑定sex属性,试图绑定sex将得到AttributeError的错误 。Traceback (most recent call last):File "F:/Python/pycharm/201705/1.py", line 14, in obj1.sex = "male"AttributeError: 'Foo' object has no attribute 'sex'
需要提醒的是,slots定义的属性仅对当前类的实例起作用,对继承了它的子类是不起作用的 。想想也是这个道理,如果你继承一个父类,却莫名其妙发现有些变量无法定义,那不是大问题么?如果非要子类也被限制,除非在子类中也定义slots,这样,子类实例允许定义的属性就是自身的slots加上父类的slots 。