Python中类方法定义及常用的实现方式

1. python类的属性和方法查看

class Person_1:
    mind = '有思想'
    belif = '有信仰'
    animal = '高级动物'


    def tt():
        pass

print(Person_1.__dict__)  #查询类Person中所有的内容,表现形式是字典.
print(Person_1.__dict__['belif'])  #查询类Person中的变量'belif'


class Person_2:
    mind = '有思想'
    belif = '有信仰'
    animal = '高级动物'
    
    def work():
        print('666')
        
    def money():
        print('777')

print(Person_2.animal)  #高级动物
print(Person_2.mind)  #有思想
Person_2.mind = '没有思想'  #修改变量'mind'的值,可以通过__dicy__查看修改后的内容
Person_2.pay = '货币交换'  #增加变量'pay'和它的值,可以通过__dicy__查看增加后的内容
Person_2.say = '语言交流'
print(Person_2.work())  #也可以调用类中的方法(函数),工作中不用类名去操作
print(Person_2.__dict__)  #查看类中所有的内容

运行:

{'__module__': '__main__', 'mind': '有思想', 'belif': '有信仰', 'animal': '高级动物', 'tt': <function Person_1.tt at 0x10f243f28>, '__dict__': <attribute '__dict__' of 'Person_1' objects>, '__weakref__': <attribute '__weakref__' of 'Person_1' objects>, '__doc__': None}
有信仰
高级动物
有思想
666
None
{'__module__': '__main__', 'mind': '没有思想', 'belif': '有信仰', 'animal': '高级动物', 'work': <function Person_2.work at 0x1114429d8>, 'money': <function Person_2.money at 0x1114421e0>, '__dict__': <attribute '__dict__' of 'Person_2' objects>, '__weakref__': <attribute '__weakref__' of 'Person_2' objects>, '__doc__': None, 'pay': '货币交换', 'say': '语言交流'}

2. python对象方法、类方法、静态方法:

下面是简单的几个例子:

class Person(object):
    
    grade=6     # 类变量
    
    def __init__(self):
        self.name = "king"
        self.age=20
        
    def sayHi(self):    #加self区别于普通函数
        print ('Hello, your name is?',self.name)
        
    def sayAge(self):
        print( 'My age is %d years old.'%self.age)
        
        
    @staticmethod     # 静态方法不能访问类变量和实例变量,也不能使用self
    def sayName():
        print ("my name is king") 
        
          
    @classmethod     #类方法可以访问类变量,但不能访问实例变量
    def classMethod(cls):  
        #print('cls:',cls)
        print('class grade:',cls.grade)        
        #print("class method")
            
        
class Child(object):
    
    def __init__(self):
        self.name = "小明"
        self.age=20
     
        
    def sayName(self,obj):
        print('child name is:',self.name)
        print(obj.sayName)
        print(obj.sayName()) # 这里要特别注意带括号和不带括号的区别:一个是对象,一个是方法
        

p = Person()    # 实例化对象
print('p.grade:',p.grade)  # 实例对象调用类变量
p.grade=9
print(p.classMethod(),p.grade) # 实例改变类变量时,其grade变量只会在实例中改变


print(Person().grade) # 类对象调用类变量
p.sayHi()       # 实例对象调用类成员函数 
Person().sayAge() # 类对象调用类成员函数


p.sayName()    # 实例对象调用类静态方法
m=Person()
m.sayName()    # 多个实例共享此静态方法
Person().sayName() # 类对象调用静态方法


p.classMethod()  # 实例对象调用类方法
Person.classMethod() # 类对象调用类方法

# 调用类
tt=Child()
tt.sayName(Person()) 

运行结果:

p.grade: 6
class grade: 6
None 9
6
Hello, your name is? king
My age is 20 years old.
my name is king
my name is king
my name is king
class grade: 6
class grade: 6
child name is: 小明
<function Person.sayName at 0x10f1cc598>
my name is king
None

小小总结下:

python中实现静态方法和类方法都是依赖于python的装饰器来实现的。 对象方法有self参数,类方法有cls参数,静态方法不需要这些附加参数。

  • 静态方法

要在类中使用静态方法,需在类成员函数前面加上@staticmethod标记符,以表示下面的成员函数是静态函数。使用静态方法的好处是,不需要定义实例即可使用这个方法。另外,多个实例共享此静态方法(静态方法无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系,简单讲,静态方法就是放在一个类的作用域里的函数而已)。

  • 类方法

类方法与普通的成员函数和静态函数有不同之处。定义: 一个类方法就可以通过类或它的实例来调用的方法, 不管你是用类来调用这个方法还是类实例调用这个方法,该方法的第一个参数总是定义该方法的类对象。 也即是方法的第一个参数都是类对象而不是实例对象. 按照习惯,类方法的第一个形参被命名为 cls。任何时候定义类方法都不是必须的(类方法能实现的功能都可以通过定义一个普通函数来实现,只要这个函数接受一个类对象做为参数就可以了)。同时,类方法可以访问类属性,无法访问实例属性。上述的变量grade,在类里是类变量,在实例中又是实例变量,所以使用的时候要注意,使用好的话功能很强大,使用不好容易混淆。

3. 类方法之间的调用

class Person(object):
    
    # 不加任何参数直接定义,也是类方法
    def Work():
        print(" I am working!")
                
    # 类方法       第一种方法:加装饰器方法
    @classmethod   
    def Think(cls,b):    #类方法Think必须要带至少1个参数,第一个参数默认为类名,后面可以引用。
        cls.Eat(b)       #在类方法Think中,调用类方法Eat类方法。
        cls.Work()       #在类方法Think中,调用Work类方法。        
        print(b,",I am Thinking!")
    

    # 属于第二种方法,先定义类方法,至少1个参数,第一个默认为类名。
    def Eat(cls,b):      
        print(b+",I am eating")
    Eat=classmethod(Eat)    #第二种方法:通过内建函数classmethod()来创建类方法。  
    
    # 静态方法,引用时直接用类名.Sleep()即可。
    @staticmethod            
    def Sleep():
        print("I am sleeping")
                        
    # 这种方法是:实例对象调用方法
    def __scolia__(self):         
        print("scola")
        return "scola"
               
    # 实例对象可以访问的私有方法,在类方法中可以相互调用和使用。类不能直接访问或者外部访问。
    def __good(self):           
        print("good")
        return "good"
    
    
Person.Think("li")
Person.Eat("jcy")
Person.Work() 
# a.Work()  报错,实例对象不能调用类方法
Person.Sleep()

a=Person()
a.__colia__() # 魔术方法,没有私有化。
#a.__good()   # 私有方法:报错了!

运行:

li,I am eating
 I am working!
li ,I am Thinking!
jcy,I am eating
 I am working!
I am sleeping
scola

4. python使用@property @x.setter @x.deleter

  • 只有@property表示只读。
  • 同时有@property和@x.setter表示可读可写。
  • 同时有@property和@x.setter和@x.deleter表示可读可写可删除。

方法必须要先经过 property()函数的装饰后,才有后面两个装饰器的用法。

直接看实例:

class student(object):  #新式类
    
    def __init__(self,id):  
        self.__id=id  
        
    @property  #只读  
    def score(self):  
        return self._score 
    
    @score.setter #只写  
    def score(self,value):          
        if not isinstance(value,int):  
            raise ValueError('score must be an integer!')    
        if value<0 or value>100:  
            raise ValueError('score must between 0 and 100')   
        self._score=value  
               
    @property #只读
    def get_id(self):  
        return self.__id  
    
  
s=student('123456')  
s.score=100 # 写  
print(s.score) #读  
print(s.__dict__)
print (s.get_id) #只读
#s.get_id=456 #只能读,不可写:AttributeError: can't set attribute


class A(object): # 新式类(继承自object类)
    
    def __init__(self):
        self.__name=None
        
    def getName(self):
        return self.__name
    
    def setName(self,value):
        self.__name=value
        
    def delName(self):
        del self.__name
        
    name=property(getName,setName,delName)
 
a=A()
print(a.name) #读
a.name='python' #写
print(a.name) #读
del a.name #删除
#print a.name #a.name已经被删除 AttributeError: 'A' object has no attribute '_A__name'

运行结果:

100
{'_student__id': '123456', '_score': 100}
123456
None
python

经典类和新式类的对比:

class test1:#经典类:没有继承object    
    def __init__(self):    
        self.__private='alex 1' #私有属性以2个下划线开头 
        
    #读私有属性    
    @property    
    def private(self):    
        return self.__private 
    
    #尝试去写私有属性(对于经典类而言,“写”是做不到的)  
    @private.setter    
    def private(self,value):    
        self.__private=value
        
    #尝试去删除私有属性(对于经典类而言,“删除”也是做不到的)  
    @private.deleter  
    def private(self):  
        del self.__private  
 

     
class test2(object):# 新式类:继承了object    
    def __init__(self):    
        self.__private='alex 2' #私有属性以2个下划线开头 
        
    #读私有属性    
    @property    
    def private(self):    
        return self.__private   
    
    #写私有属性    
    @private.setter    
    def private(self,value):    
        self.__private=value  
        
    #删除私有属性  
    @private.deleter  
    def private(self):  
        del self.__private  
      
t1=test1()    
#print t1.__private # 外界不可直接访问私有属性    
print (t1.private) # 读私有属性
print (t1.__dict__) 
t1.private='change 1' #对于经典类来说,该语句实际上是改变了实例t1的实例变量private  
print (t1.__dict__)
print (t1.private) # 输出刚刚添加的实例变量private  

t1.private='change 2'  
print (t1.__dict__)  
del t1.private # 删除刚刚添加的实例变量private  
print (t1.__dict__) 
#print (t1.private) #读私有属性,因为已经删除,所以这里会报错

print ('-------------------------------------------------------')
t2=test2()    
print (t2.__dict__)  
print (t2.private) # 继承了object,添加@private.setter后,才可以写    
t2.private='change 2' # 修改私有属性    
print (t2.__dict__)   
print (t2.private)  
del t2.private #删除私有变量  
#print t2.private #私有变量已经被删除,执行“读”操作会报错:AttributeError: 'test2' object has no attribute '_test2__private'    
print (t2.__dict__) 

运行:

alex 1
{'_test1__private': 'alex 1'}
{'_test1__private': 'change 1'}
change 1
{'_test1__private': 'change 2'}
{}
-------------------------------------------------------
{'_test2__private': 'alex 2'}
alex 2
{'_test2__private': 'change 2'}
change 2
{}

貌似差别也不是很大。

参考:
https://blog.csdn.net/sxingming/article/details/52916249

5. “魔术方法”的使用

可以参考:https://blog.csdn.net/NightCharm/article/details/79357559

你可能感兴趣的:(python)