@classmathod, @staticmethod and some other class __str__

 #------@staticmethod-------
'''
class Iphone(object):
    def __init__(self):
        pass
    @staticmethod
    def barking(self):
        print('I like barking')
hululu=Iphone()
#hululu.barking() #这样会报错 因为这样barking就是一个普通的函数了不属于类了
 #-------------静态方法 实际上跟类没什么关系了,就是把方法跟类的关系打断了--------------

#-----------------@classmethod类方法:就是只能访问类变量 而不能访问实例变量---------------------
#这样的话 可以用 相同名字的类变量 来锁住实例里的变量

class Iphones(object):
    name='iphone' #相当于一个锁 
    def __init__(self,name):
        self.name=name
    @classmethod #相当于一个锁 
    def barking(self):
        print('I like %s'%(self.name))
lili=Iphones('iphoneX')
lili.barking()

#-----------------@property 属性方法:把方法变成了静态属性--------------------------------
#可以简单的调用 而不用在调用方法加括号
class IphoneX(object):
    
    def __init__(self,name):
        self.name=name

    @property
    def barking(self): #这样这里就是一个属性了 而不是一个方法了
        print('I like %s'%(self.name))
#———————@barking.setter的作用就是用新的函数完全替代另外一个函数,但一定要给其赋值——————————————————————————

    @barking.setter
    def dangdang(self,name):    
        print('I wanna buy',name)

#----------如果是相同的名字就是 在不改变名字的情况下 修改原函数。--------------------     
    @barking.setter
    def barking(self,name):
        print('I wanna change old barking content %s'%name)

lili=IphoneX('iphoneX') 
lili.barking
lili.dangdang='hello'
lili.barking='new'

# ------------------这里是@property 的例子2 如何给属性方法赋值-------------------

class Flight(object): 
    
    def __init__(self,name):
        self.flight_name = name

    def checking_status(self):
        print("checking flight %s status " % self.flight_name)
        return  1

    @property
    def flight_status(self):
        status = self.checking_status()
        if status == 0 :
            print("flight got canceled...")
        elif status == 1 :
            print("flight is arrived...")
        elif status == 2:
            print("flight has departured already...")
        else:
            print("cannot confirm the flight status...,please check later")
    
    @flight_status.setter #修改
    def flight_status(self,status): #status_dic.get(status) 用.get(key)来得到value的值!!!!!!!!!!!!!!!!!!!
        status_dic = {
            0 : "canceled",
            1 :"arrived",
            2 : "departured"
        }
        print("\033[31;1m Has changed the flight status to \033[0m",status_dic.get(status))

    @flight_status.deleter  #删除
    def flight_status(self):
        print("status got removed...")

f = Flight("CA980")
f.flight_status
f.flight_status =  2 #触发@flight_status.setter 这样直接可以修改 f.flight_status的值
del f.flight_status #触发@flight_status.deleter 这里可以删除这个属性
print(Flight.__doc__)


# --------------Flight. __doc__ 表示类的描述信息 " ''' ''' " 这中间的信息 -----------------
__doc__
# --------------Flight. __module__ 表示当前操作的对象在那个模块 -----------------
__module__ 表示当前操作的对象在那个模块
# --------------Flight. __class__表示当前操作的对象的类是什么 -----------------
__class__ 表示当前操作的对象的类是什么


class C:

    def __init__(self):
        self.name = 'wupeiqi'

from lib.aa import C

obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类


# ------------------------------__call__--------------------------------
# ----------------------------------------------------------------------
# __call__ 对象后面加括号,触发执行。相当于有了这个方法,我们实例名后面加()就可以执行这个__call__

注:构造方法的执行是由创建对象触发的,即:对象 = 类名();而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass     
    def __call__(self, *args, **kwargs):
        print '__call__'
 
obj = Foo() # 执行 __init__
obj()       # 执行 __call__

 # ---------------------------------------------------------------------
 # -----------------------------__dict__获取类中的构造函数中的信息--------------------------------
                                # 并以字典的模式来显示
 class Province:
 
    country = 'China'
 
    def __init__(self, name, count):
        self.name = name
        self.count = count
 
    def func(self, *args, **kwargs):
        print 'func'
 
print Province.__dict__ 
# 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
# 获取类中所有的属性,不包括实例属性

obj1 = Province('HeBei',10000)
print obj1.__dict__
# 获取 对象obj1 的成员,打印所有的实例属性
# 输出:{'count': 10000, 'name': 'HeBei'}
 
obj2 = Province('HeNan', 3888)
print obj2.__dict__
# 获取 对象obj1 的成员,打印所有的实例属性
# 输出:{'count': 3888, 'name': 'HeNan'}

# ---------------------------------------------------------------------
# ------------------------------__str__--------------------------------

__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class Foo:
 
    def __str__(self):
        return 'alex li'
obj = Foo()
print obj
输出:alex li 
如果没有__str__这样输出实例是一个内存地址,但是用__str__后就可以得到一个直接确切的值


# ---------------------------------------------------------------------
# --------------__getitem__、__setitem__、__delitem__--------------------------------
'''
# 用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):
    def __init__(self):
        self.dict={}
 
    def __getitem__(self,key):
        print('__getitem__',key)
        return self.dict.get(key)
 
    def __setitem__(self, key, value):
        print('__setitem__',key,value)
        self.dict[key]=value
 
    def __delitem__(self, key):
        print('__delitem__',key)
 
 
obj = Foo()
 
print(obj['k1'])      # 自动触发执行 __getitem__ 可以会得到key 
obj['k2'] = 'alex'   # 自动触发执行 __setitem__ 这里可以直接赋值
del obj['k1']