Python中类方法定义及常用的实现方式_python 类内声明 类外实现-程序员宅基地

技术标签: python  静态方法  类方法  魔术方法  @property  

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lilong117194/article/details/83506399

智能推荐

基于不确定混沌系统的无抖振模糊滑模变结构控制策略matlab仿真-程序员宅基地

文章浏览阅读140次。在非线性控制系统中,尤其是存在不确定性、时变性和复杂动力学特性的混沌系统,滑模变结构控制(Sliding Mode Control, SMC)因其强大的鲁棒性和对系统扰动的不敏感性而受到关注。然而,传统滑模控制在切换过程中会产生较大的抖振现象。为了解决这一问题,引入了模糊逻辑来设计一种无抖振模糊滑模控制器。

嵌入式C语言编程——.h文件与.c文件-程序员宅基地

文章浏览阅读2.1k次。.h文件与.c文件的关系参考高手的程序时,发现别人写的严格的程序都带有一个“KEY.H”,里面定义了.C文件里用到的自己写的函数,如Keyhit()、Keyscan()等。.H文件..._c语言 编写.c和.h文件示例

人脸数据集——亚洲人脸数据集-程序员宅基地

文章浏览阅读3.6w次,点赞30次,收藏126次。大规模亚洲人脸数据的制作 在这次大规模亚洲人脸数据制作主要是亚洲明星人脸数据集,此次我爬取了大概20万张亚洲人脸图像,可以修改爬取每位明星图片的数量来获取更多的图片,过程中主要分以下几步: 获取明星名字列表 (1)、首先从百度搜索栏中搜索“明星”,显示出明星栏目,地区包括内地、香港、台湾、韩国和日本,如下图:(2)、使用python爬虫将这些明星的名字爬取下来,代码如下所...

章鱼哥出品—VB.NET 自定义快捷键使用详解之全局热键_vb.net 中窗体快捷键如何设置为alt+p-程序员宅基地

文章浏览阅读7.5k次,点赞2次,收藏21次。如何设置VB.NET 窗体的全局热键(快捷键),_vb.net 中窗体快捷键如何设置为alt+p

Win7 装 Ubuntu 双系统,不需要U盘_win7无u盘安装ubuntu18.04-程序员宅基地

文章浏览阅读9.8k次。本文测试安装的是32位的ubuntu-14.10-desktop-i386.iso 系统。准备: Ubuntu系统ISO文件。官网或者学校的镜像源可下。 UltraISO 软件。 Google 搜一下,可用试用版就行。主要用于从ISO文件里提取文件。 EasyBCD 软件。 Google 一下。Step 1. 计算机右键,管理,_win7无u盘安装ubuntu18.04

远程命令/代码执行漏洞(RCE)总结_rec 远程-程序员宅基地

文章浏览阅读6.6k次,点赞18次,收藏80次。文章目录介绍PHP命令执行函数代码执行函数命令拼接符命令执行的一些绕过技巧绕过str_replace()函数空格被过滤的绕过用编码来绕过URL编码绕过Base64编码绕过Hex编码绕过Oct编码绕过:偶读拼接绕过(黑名单绕过)花括号{command,}的别样用法无回显的命令执行方法一:反弹shell方法二:msf反向回连利用RCE反弹Shellnetcat 一句话反弹Shellbash反弹shel..._rec 远程

随便推点

SAP ABAP程序性能优化 2-程序员宅基地

文章浏览阅读5.7k次。以下是以前看到的一些关于SAP ABAP程序性能优化的东西 As you all know, it is important to use as many key fields as possible in WHERE clauses of SELECT statements. Sometimes you are not sure about the value of some key field

访问控制及数字签名技术-程序员宅基地

文章浏览阅读709次,点赞24次,收藏15次。互联网络的蓬勃发展,为信息资源的共享提供了更加完善的手段,企业在信息资源共享的同时也要阻止非授权用户对企业敏感信息的访问。的目的是为了保护企业在信息系统中存储和处理的信息的安全。

asm/semaphore.h: No such file or directory_qt 找不到semaphore.h-程序员宅基地

文章浏览阅读3.3k次。当我进行内核hook的时候,包含的# include头文件,编译的时候系统提示找不到这个文件或者目录,然后去谷歌搜的,上面说这个头文件已经被移动到linux/semaphore.h,所以将头文件包含改为#include这个问题就解决了。_qt 找不到semaphore.h

解决:interface conversion: interface {} is float64, not int-程序员宅基地

文章浏览阅读8.4k次,点赞7次,收藏4次。目录前言 正文 结尾前言今天遇到一个小坑,但是自己陷进去好久,说起来有些不好意思,但是感觉还是应该拿出来晒一晒,希望大家别再被类似的问题耽误了。解析下面的 json 结构:"video": { "width": 1280, "height": 720}首先,我们把问题简化,假设我们拿到了 map[string]interface{} 类型的 video 实例,如何基于 video 实例读取 width 和 height 的值,注意是整形数值,不是_interface conversion: interface {} is float64, not int

三维重建的定位定姿算法-程序员宅基地

文章浏览阅读503次。点击上方“3D视觉工坊”,选择“星标”干货第一时间送达作者丨李城编辑丨计算机视觉工坊点击进入—>3D视觉工坊学习交流群3D视觉的核心问题是恢复场景结构、相机位姿、和相机参数,而解决方式有两种,一种是off-line的sfm(structure from motion),一种on-line的slam(simultaneous localization and mapping)。Slam 与sf..._global rotation

1到n的数按字典序排序_输出从 11 到 nn 所有数字的所有排列方式,按字典序排序。-程序员宅基地

文章浏览阅读5.6k次。#coding:utf-8'''今日头条2017秋招编程题输入:n,m输出从 1 到 n 的数按 字典序 排序的低 m 个数如输入:11 41 10 11 2 3 4 5 6 7 8 9 中的第四个数输出: 2'''import numpy as npfrom numpy import *s = raw_input()s = s.split(' ')n = int(s[0])m = int(s[1_输出从 11 到 nn 所有数字的所有排列方式,按字典序排序。

推荐文章

热门文章

相关标签