python之对象

类与对象

类就是定义种类的东西的方式,它反映了在程序领域中的真实对象。对象则是类创建的实例。类是一种产生实例的工厂

class Foo:
  def __init__(self):
    pass
  def buy(self)
    pass
obj = Foo()

在上面,Foo就是一个类,而obj则是类创建的实例-->对象。

继承

在python中,实例从类中继承,而类继承于父类。

class Foo:
  def __init__(self):
    pass
  def buy(self)
    pass

class Foo1(Foo):
  def buy(self):
    print("buy")

当子类调用父类方法时,使用super()方法

class Foo1(Foo):
  def __init__(self):
    super().__init()

类的特性

静态字段:

静态字段存在类中,如

class Foo:
  def __init__(self,name):
    self.name = name
  country = 'China'

country就是静态字段,self.name就是普通字段

普通字段属于对象,而静态字段则属于类(根据命令空间可知)。当对象在搜索属性时(obj.country),会在对象内搜索属性,然后在其上所有可读的类(使用继承搜索流程)静态字段在内存中只保存一份,而普通字段第个对象都要保存一份。对象中共同的字段可以用静态字段,这样就不用重复创建字段,在类中保存一份。

静态方法

由类调用,通过staticmethod装饰;类方法,由类调用,至少有一个cls参数,执行类访问时,自动将调用该方法的类复制给cls。普通方法,由对象调用,至少有一个self参数,执行该方法时,自动将点号前面的对象(执行方法的对象)赋给self。

class Foo:
  @staticmethod       #静态方法
  def func(arg1, arg2):
    print(arg1, arg2)

  @classmethod       #类方法
  def func1(cls):
    print(cls)

  def func2(self):         #普通方法
    print("normal method")
obj = Foo()
obj.func(1,2)
obj.func1()  
obj.func2()

相同点,对于所有方法而言,均属于类中,所以只在内在中保存一份
不同点,方法调用者不同,调用方法传入的参数也不同。

方法当作字段访问

class Foo:
  @property
  def show(self):
    print('show')
Foo.show

当方法作字段时,可以像字段那样进行修改,但是需要装饰

class Foo
  @property      
  def show(self):
    print('show')
  @end.setter
  def show(self):
    pass


obj = Foo()
obj.end= '123'

成员修饰符

私有成员,只能内部访问,只能自己访问,子类也不能访问

class Foo:
	__name = '...'     #私有成员
	def fetch():
		print(__name)
Foo.fetch()

但是可以通过 _类名__name 访问

对象后面加括号:

	obj = Foo()
	obj()   #执行对象的__call__ 方法

索引与分片

对实例的索引和分片运算,调用__getitem__方法。赋值使用__setitem__方法。

class Foo:
  data = [1,2,3,4,5]
  def __getitem__(self, index):
    return self.data[index]
  def __setitem__(self, index, value):
    self.data[index] = value
  def __delitem__(self, index):
    pass
obj = Foo()
obj['abc'] = 'abc'  #当通过索引赋值,则会调用__setitem__
del obj['abc']  #通过索引删除时,调用__delitem
ret = obj['abc']   #通过索引取值,调用__getitem__

_ __getitem__也可以是python中一种重载迭代的方式 。如果在类中定义了这个方法,则for在每次循环时都会调用_getitem_ 这个方法。 _

class Foo:
  def __getitem__(self, index):
    return self.data[index]
obj = Foo()
obj.data = [1,2,3,4,5]
for i in obj:
  print(i, end=' ')
#结果----> 1 2 3 4 5

索引使用get/setitem 而点号使用get/settattr方法,在反射上用到这两个方法。判断和获取方法。而导入模块则用_import_()这个方法

属性引用

当进行点号运算时,则会调用__getattr__方法。

class Foo:
  #重写__getattr__
  def __getattr__(self, attrname):
    if attrname == 'age':
      return 40
    else:
      raise AttributeError,attrname

obj = Foo()
obj.age   #return 40
obj.name  #return error

而进行属性赋值时,则调用__setattr_方法
如obj.name='xxx',则内部会调用self._setattr_('attr', value)。而赋值操作又会调用_setattr_
,导致无穷递归循环。如果想使用这个方法,则要通过字典做索引运算来做赋值。

class Foo:
  def _setattr__(self, attr, value):
    self.__dict__[attr] = value

obj = Foo()
obj.name='xxoo' #赋值操作调用__setattr__方法

迭代器对象

之前我们使用了__getitem__方法来迭代对象,但python中的所有迭代都使用__iter__方法。迭代环境是通过调用内置函数iter去尝试寻找__iter__方法来实现的,而这种方法应该返回一个迭代器对象,如果己经提供,python就会重复调用这个迭代器的next方法,直到发生异常。如果没有找到__iter__方法,则会调用 __getitem__方法。

class Foo:
  def __init__(self, start, stop):
    self.value = start - 1
    self.stop = stop
  def __iter__(self):
    return self
  def __next__(self):
    if self.stop == self.value:
      raise StopIteration
    self.value += 1
    return self.value ** 2

obj = Foo(1,5)
for i in obj:
  print (i)   #结果 --->1,4,9,16,25
X = foo(1,10)
I = iter(X)
next(I)  #1
next(I)  #4
原文地址:https://www.cnblogs.com/baitutu/p/6271254.html