Python 类

@classmethod 修饰的函数在类中执行,不在实例中运行。
@staticmethod 静态方法:处理一些 跟类有关系但在运行时又不需要实例和类参与的功能。

python 类

1.定义:
例:

class Bird(object):
  have_feather = True
  reproduction = 'oviparous'
  def greet(self):             ## self代表了一个对象,对象拥有类的所有性质
    return "hello"

object:说明这个类没有父类
have_feather、reproduction:是类的属性
greet:是类的方法

2.类的引用:
类的引用方式有两种,属性引用和实例化,以下对比来看。
1)简介:

if __name__ == "__main__":
    ##  属性引用
    f = Bird.have_feather 
    print f
    ret = Bird().greet()
    print ret
    ##  类的实例化
    sparrow = Bird()
    print sparrow.have_feather
    print sparrow.greet()

输出:
True
hello
True
hello

2)对比

if __name__ == "__main__":
    print Bird.have_feather          #True
    ## 属性引用 
    ## 改变类中的属性的值,类中的属性值改变,类改变后再创建的实例--->实例的属性也是改变后的。
    Bird.have_feather = False 
    print Bird.have_feather          #False
    bird = Bird()
    print bird.have_feather          #False
    Bird.have_feather = True
    ## 类的实例化 
    ## 对实例中的属性进行操作,不影响类的属性,也不会影响其他实例中该属性的值。
    bird.have_feather = Fales
    print bird.have_feather          #False
    print Bird.have_feather          #True
    bird2 = Bird()
    print bird2.have_feather         #True

输出:
True
False
False
False
True
True

3)创建有初始状态的类 init

class Bird(object):
  def __init__(self,extend={'can_run':False,'direction':'N','distance':0}):
    self.extend = extend
    self.can_run = extend['can_run']
    self.direction = extend['direction']
    self.distance = extend.get('distance')
  can_fly = True
  run_distance = 0
  run_direction = ''
  have_feather = True
  reproduction = 'oviparous'
  def run(self,others=0):                ## 这里run方法还有一个外部参数others,默认值为0
    can_run = self.can_run
    if can_run is True:
      self.run_direction = self.direction
      self.run_distance += self.distance+others
      print "can"
    else:
      self.run_direction = 'stop'
      self.run_distance += 0
      print "cann't"
  def get_run_info(self):
    return self.run_direction,self.run_distance

创建具有初始状态的类可以通过init方法来实现,类的实例化操作,将会为新建的
类的实例自动调用init方法。
以上,Bird类中run方法每次调用都会修改对象的run_distance、run_direction两个属性。
这里的对象其实可以看做是类的一个实例。

if __name__ == "__main__":
  extend = {'can_run':True,'direction':'N','distance':5}
  ## 用类的实例
  sparrow = Bird(extend)
  sparrow.run()                ## run方法让sparrow实例的属性run_distance 、run_direction发生了变化
  print sparrow.get_run_info() 
  ## 用属性引用的方式调
  Bird(extend).run(-10)        ## 这样会有问题,因为run方法是通过self让对象的属性改变,但这里没有定义对象。×
  print Bird().get_run_info()  ## ×

输出:
can
(‘N’,5)
can
(”, 0)

3.类的继承-子类
1) 派生类(子类)必须与基类(父类)在同一作用域。
例:
定义一个类Chicken继承Bird类,没有初始化。
定义一个类Ostrich集成Bird类,有初始化。

class Chicken(Bird):
  can_fly = False             ## 对Bird 类的属性进行了改写
  def cook(self,mod=''):
    return "delicious {} chicker".format(mod)

## Chicken 子类没有__init__ 则仍通过父类Bird()的__init__初始化
## Ostrich 子类有 __init__ 会通过Ostrich()类的__init__初始化,而不是Bird父类。
## 所以如果父类对象的属性会被使用需要在子类中重新定义一遍。

class Ostrich(Bird):
  def __init__(self,extend={'food':'rice'}):
    self.extend = extend
    self.food = extend['food']
    self.can_run = extend['can_run']          ##    如果还要使用父类的属性,或
    self.direction = extend['direction']      ## 使用父类的方法时,父类的属性在
    self.distance = extend.get('distance')    ## 父类的方法中被使用。都需要在init
                                              ## 中,接收进self定义
  def eat(self):
    self.food=self.extend['food']
  def get_eat_info(self):
    return self.food

创建一个Chicken类的实例,它将可以获得Bird类的属性和方法。

if __name__ == "__main__":
  sparrow = Chicken()
  print sparrow.can_fly        ## 子类中重新定义了父类的属性
  print sparrow.have_feather   ## 子类继承父类中的属性
  print sparrow.reproduction    
  sparrow.run()                ## 子类中继承的父类中的方法
  print sparrow.get_run_info() 
  extend = {'food':'grass','can_run':True,'direction':'N','distance':5}
  sparrow2 = Chicken(extend)
  sparrow2.run()
  print sparrow2.get_run_info()
  print "--------------------------"
  extend = {'food':'grass','can_run':True,'direction':'N','distance':5}
  ostrich = Ostrich(extend)
  ostrich.eat()                 ## 子类自己的方法
  print ostrich.get_eat_info()  
  print ostrich.reproduction    ##reproduction是Ostrich父类Bird中的属性
  ostrich.run()                 ## run()Ostrich 父类Bird中的方法。 
  print ostrich.get_run_info()

输出:
False
True
oviparous
cann’t
(‘stop’, 0)
can
(‘N’, 5)


grass
oviparous
can
(‘N’, 5)

2)多继承-不建议轻易使用
解析类属性的规则:深度优先,从左到右

class A(object):
  def __init__(self):
    print "I'm A"
  ab = 'a'

class B(object):
  def __init__(self):
    print "I'm B"
  ab = 'b'

class A2(A):
  def __init__(self):
    print "I'm A2"
  a2 = 'a2'
if __name__ == "__main__":
  c = C()
  print c.ab
## A B都有ab属性,C(A,B)
I'm A
a
## A B都有ab属性,C(B,A)
I'm B
b
## A B都有ab属性 ,A2(A),C(B,A,A2)
## 无法建立一致的方法解析 ×
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases B, A, A2
## A B都有ab属性 ,A2(A),C(B,A2,A)
I'm B
b

4.补充:self的用法
上面,在People类的eat方法中,可以通过self.food的方式调用该类的属性food,
同样,通过self.eat()、self.get_eat_info()的方式也可以调用该类中的方法。

class People(Bird):
  def __init__(self,extend):
    self.extend = extend
  food = ''
  def eat(self):
    self.food=self.extend['food']
  def get_eat_info(self):
    return self.food
  def three_meals(self):
    for times in range(3):
      self.eat()
      print self.get_eat_info()
if __name__ == "__main__":
  extend = {'food':'rice'}
  xiaoming = People(extend)
  xiaoming.three_meals()

输出:
rice
rice
rice

self其实是类的实例在类内部的表示,也就是说在eat方法中self.food=…其实是对实例中
的属性进行了修改。用一段代码解释一下:

if __name__ == "__main__":
  extend = {'food':'rice'}
  xiaoming = People(extend)
  xiaoming.eat()
  print xiaoming.get_eat_info()    ## rice
  print xiaoming.food              ## rice

输出:
rice
rice

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值