装饰一个类及内部方法
通过装饰器函数修改一个类属性
class MyClass:
NAME = 'My CLASS HAHAHA'
def __init__(self):
pass
print(MyClass.__dict__['NAME'])
My CLASS HAHAHA
等价于:
def setname(name):
def warpper(cls):
cls.NAME = name
return cls
return warpper
@setname('MY CLASS enen') #
class MyClass:
pass
print(MyClass.__dict__['NAME'])
MY CLASS enen
例2:
class MyClass:
def foo(self):
print('foo')
def bar():
print('bar')
a = MyClass()
a.bar()
报错如下:
File "E:\python_project\class_test.py", line 12, in <module>
a.bar()
TypeError: bar() takes 0 positional arguments but 1 was given
提示最少需要给予一个参数才可以
这么写的意思是,函数是普通函数,但是实例化之后是无法使用
这样是不符合规定的
改进:
使用装饰器,第一个装饰器使用类方法
@classmethod
class MyClass:
xxx = 'hahaha'
def foo(self):
print('foo')
def bar():
print('bar')
@classmethod
def clsmtd(cls):
print('{}.xxx = {}'.format(cls.__name__,cls.xxx))
a = MyClass()
a.foo()
MyClass.bar()
print(MyClass.__dict__)
foo
bar
{'xxx': 'hahaha', 'bar': <function MyClass.bar at 0x0000000000DD0488>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None, 'foo': <function MyClass.foo at 0x0000000000DD0400>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__module__': '__main__', 'clsmtd': <classmethod object at 0x0000000000DD70F0>}
a.clsmtd()
MyClass.xxx = hahaha
静态方法使用
staticmethod
class MyClass:
def foo(slef):
return('foo')
def bar():
return('bar')
@staticmethod
def staticmtd():
return('static')
a = MyClass()
print(MyClass.staticmtd())
print(a.staticmtd())
static
static
是类的方法即是所有对象的方法
py中的静态方法,表示最一般的函数放在静态方法中,但是受其管辖
然后测试bar方法是否可用
@staticmethod
def bar():
return('bar')
a = MyClass()
print(a.bar())
bar
类方法
class Person:
def haha():
print('haha')
Person.haha()
haha
由于没有跟self,没有完成实例的绑定,所以不能完成实例对象的绑定,所以不能用
Person().haha()
TypeError: haha() takes 0 positional arguments but 1 was given
Person().haha()
语法是对的,但是禁止这么调用
@classmethod
class Person:
HEIGHT = 16
@classmethod
def class_method(cls):
print('class = {0.__name__} ({0})'.format(cls))
cls.HEIGHT = 17
Person.class_method()
print(Person.HEIGHT)
for i in Person.__dict__.items():
print(i)
返回如下:
class = Person (<class '__main__.Person'>)
17
('class_method', <classmethod object at 0x0000000000DA1278>)
('__weakref__', <attribute '__weakref__' of 'Person' objects>)
('__doc__', None)
('HEIGHT', 17)
('__module__', '__main__')
('__dict__', <attribute '__dict__' of 'Person' objects>)
在类定义中,使用@classmethod装饰器修饰方法
至少有一个参数,而且第一个参数留给了cls,cls表示调用即类对象自身
cls表示标识符,可以是任意名称,但是为了易读性
类方法是可以直接调用,而实例的方法要求实例必须存在,但是类存在的时候实例可能不存在
只要类方法定义过了,类对象就产生了,那么找属性即可找到
调用方法总结
代码如下:
class Person:
def no():
print('no')
def method(self):
print('{} method'.format(self))
@classmethod
def class_method(cls):
print('class = {0.__name__} ({0})'.format(cls))
cls.HEIGHT = 170
@staticmethod
def static_method():
print(Person.HETGHT)
方法调用
类的调用
print(Person.class_method())
class = Person (<class '__main__.Person'>)
print(Person.static_method())
不能调用
print(tom.method())
<__main__.Person object at 0x0000000000A97160> method
print(tom.class_method())
class = Person (<class '__main__.Person'>)
print(tom.static_method())
不可以,没有传递对象
除了普通方法都可以调用,但是普通方法都需要对象的实例作为第一参数
实例可以调用所有类中定义的方法,类和静态方法
访问控制
访问控制主要为了保护封装不被破坏,但是python对外是可见的
私有属性
属性名前加入两个下划线表示当前方法不被破坏
class Person:
age = 3
height = 170
def __init__(self,name,age=18):
self.name = name
self.age = age
def growup(self,incr=1):
if 0 < incr < 150:
self.__age + incr
tom = Person('tom')
tom.age = 200
class Person:
age = 3
height = 170
def __init__(self,name,age=18):
self.name = name
self.age = age
def growup(self,incr=1):
if 0 < incr < 150:
self.__age + incr
def getage(self):
return self.__age
print(Person('tom').getage)
<bound method Person.getage of <__main__.Person object at 0x0000000000827208>>
class Person:
def __init__(self,name,age=18):
self.name = name
self.__age = age
def growup(self,incr=1):
if 0 < incr < 150:
self.__age += incr
# 获取内部属性
def getage(self):
return self.__age
tom = Person('tom')
tom.growup(10)
print(tom.getage())
28
修改tom._Person__age
print(tom.getage())
tom._Person__age = 200
print(tom.getage())
200
查看tom.__dict__
print(tom.__dict__)
{'_Person__age': 200, 'name': 'tom'}
得到的字典中,其实是新加了一个key,而并非被覆盖
所以py的外界是可以修改的隐藏方法的
新增加key:
tom._Person__ages = 200
print(tom.getage())
print(tom.__dict__)
{'name': 'tom', '_Person__age': 20, '_Person__ages': 200}
私有变量的本质
使用__变量名 时,会将其改名,转为_类名+前缀,所以原来名字访问不到了
知道了这个名称则可以直接修改
print(a.__dict__)
{'name': 'tom', '_Person__age': 19}
保护变量
在变量前加一个下划线,共同的约定,表示提醒你这个是一个内部私有的
而解释器认为私有的是私有变量
装饰一个类及内部方法相关推荐
- Java反射机制demo(五)—获得并调用一个类中的方法
这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和运行结果.获取所有的方法使用Class类中getMetho ...
- java有且只有一个什么_1. 一个Java应用程序必须且只有一个类含有 main_____ 方法....
1.一个Java应用程序必须且只有一个类含有main_____方法.2.构造方法是一种特殊方法,它的名字必须与它所在的类的名字完全相同,并不返回任何数据类型.3.子类自然地继承了其父类中不是... 1 ...
- 一个java应用程序必须且只有一个类含有什么方法_JAVA简答题!!!
Java简答题 1.简述java语言的特点? 1.2 Java语言是目前使用最为广泛的网络编程语言之一(1分) 具有面向对象(1分) 与平台无关性(1分) 多线程性(1分) 动态性等特点(1分) 2. ...
- 将控件关联的变量值传递到另外一个类中的方法
今天在修改V1.1的一个bug:当向一个场景中加入已存的模型时会提示模型已存在,要求更改模型名称. 具体步骤如下: 1.新建一个对话框,ID为:IDD_RENAME,在此对话框中添加一个Edit控件, ...
- 如何使用一个类里面的方法
导包 首先,想要使用这个类里面的方法就要先对该类导包. 使用Import关键字在该类的所有代码之前进行导包,引入你想要的使用的类,其中java.lang是缺省的,是java的基础包,包里面的类不用导入 ...
- 查找一个类的好方法,可节省做很多层的传递
//该方法用于查询 NQGrid 对象. 参数必须是 NQGrid 里面包含的子对象 + (NQGrid*)searchNQGridWithChild:(UIView*)childView; { // ...
- 如何使用IDEA 显示一个类的所有方法?与eclipse的outline视图类似
- python装饰器类-Python 装饰器装饰类中的方法
title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...
- python装饰器实例-基于Python 装饰器装饰类中的方法实例
title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...
最新文章
- html脚本语言居中,web前端:CSS--几种常用的水平垂直居中对齐方法
- mysql 中的事务
- 阅读准备-构建redis容器
- php定位和天气,基于thinkphp实现依据用户ip判断地理位置并提供对应天气信息的应用...
- 二叉树的遍历(堆栈)
- 操作系统上机题目(多进程1)
- PHP与MYSQL数据库链接方法
- nginx 下开启pathinfo模式
- LeetCode刷题(40)--Search a 2D Matrix
- UVA10427 Naughty Sleepy Boys【数学】
- SCCM2012升级SP1系列之配置管理SCCM2012④配置SCCM2012补丁分发
- SPF邮件伪造漏洞测试脚本
- JVM垃圾收集器笔记整理
- Tomcat8安装配置
- Edge浏览器支持IE内核 / 增加Edge兼容性
- java 计算8+88+888+......前12项之和
- 上线切换 - 如何导入在制品
- 313day(服务器的一些问题)
- 教您用数学课件制作工具演示线变二面角
- php用css改变字体,css怎么设置字体立体