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.****.net/sxingming/article/details/52916249
5. “魔术方法”的使用
可以参考:https://blog.****.net/NightCharm/article/details/79357559
下一篇: Python 类编程秘诀:从小白到大师
推荐阅读
-
C++ 中的抽象类和抽象方法
-
在 ts 中实现类 java hashmap 的简单方法
-
10bit YUV(P010)的存储结构和处理-随着计算机处理信息的能力越来越厉害,这种能表现更高动态范围的图像存储格式将会逐渐成为主流,但是现在很多算法都不能直接处理 10bit 的 YUV ,都是先将其转换为 8bit YUV ,然后再进行处理,这实际上是丢弃了 10bit YUV 的图像高动态范围优势。 令人遗憾的是在渲染图像时,目前 OpenGL 也无法直接对 10bit YUV 进行渲染,也是需要先转换为 8bit YUV 。 接下来以一种常见的 10bit YUV (P010) 格式为例,介绍一下 10bit YUV 到 8bit YUV 的转换过程。 P010 最早是微软定义的格式,表示的是 YUV 4:2:0 的采样方式,也就是说 P010 表示的是一类 YUV 格式,它的内存排布方式可能是 NVNVYUYV12 。
-
Python实现具备单一目标、多目标、多尺度和自定义特征的KCF跟踪算法实例代码
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
解析Python中的类的方法和概念
-
Python中的大顶堆和小顶堆:实现从小到大排序的大顶堆
-
配置HP FC存储设备多路径驱动的方法在linux和Windows操作系统中即可实现
-
使用matplotlib在Python中实现正弦信号的时域波形和频谱图示例
-
在JSP中引入Java和Vue的实现方法