通过装饰器函数修改一个类属性

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}

保护变量

在变量前加一个下划线,共同的约定,表示提醒你这个是一个内部私有的

而解释器认为私有的是私有变量

装饰一个类及内部方法相关推荐

  1. Java反射机制demo(五)—获得并调用一个类中的方法

    这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和运行结果.获取所有的方法使用Class类中getMetho ...

  2. java有且只有一个什么_1. 一个Java应用程序必须且只有一个类含有 main_____ 方法....

    1.一个Java应用程序必须且只有一个类含有main_____方法.2.构造方法是一种特殊方法,它的名字必须与它所在的类的名字完全相同,并不返回任何数据类型.3.子类自然地继承了其父类中不是... 1 ...

  3. 一个java应用程序必须且只有一个类含有什么方法_JAVA简答题!!!

    Java简答题 1.简述java语言的特点? 1.2 Java语言是目前使用最为广泛的网络编程语言之一(1分) 具有面向对象(1分) 与平台无关性(1分) 多线程性(1分) 动态性等特点(1分) 2. ...

  4. 将控件关联的变量值传递到另外一个类中的方法

    今天在修改V1.1的一个bug:当向一个场景中加入已存的模型时会提示模型已存在,要求更改模型名称. 具体步骤如下: 1.新建一个对话框,ID为:IDD_RENAME,在此对话框中添加一个Edit控件, ...

  5. 如何使用一个类里面的方法

    导包 首先,想要使用这个类里面的方法就要先对该类导包. 使用Import关键字在该类的所有代码之前进行导包,引入你想要的使用的类,其中java.lang是缺省的,是java的基础包,包里面的类不用导入 ...

  6. 查找一个类的好方法,可节省做很多层的传递

    //该方法用于查询 NQGrid 对象. 参数必须是 NQGrid 里面包含的子对象 + (NQGrid*)searchNQGridWithChild:(UIView*)childView; { // ...

  7. 如何使用IDEA 显示一个类的所有方法?与eclipse的outline视图类似

  8. python装饰器类-Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  9. python装饰器实例-基于Python 装饰器装饰类中的方法实例

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

最新文章

  1. html脚本语言居中,web前端:CSS--几种常用的水平垂直居中对齐方法
  2. mysql 中的事务
  3. 阅读准备-构建redis容器
  4. php定位和天气,基于thinkphp实现依据用户ip判断地理位置并提供对应天气信息的应用...
  5. 二叉树的遍历(堆栈)
  6. 操作系统上机题目(多进程1)
  7. PHP与MYSQL数据库链接方法
  8. nginx 下开启pathinfo模式
  9. LeetCode刷题(40)--Search a 2D Matrix
  10. UVA10427 Naughty Sleepy Boys【数学】
  11. SCCM2012升级SP1系列之配置管理SCCM2012④配置SCCM2012补丁分发
  12. SPF邮件伪造漏洞测试脚本
  13. JVM垃圾收集器笔记整理
  14. Tomcat8安装配置
  15. Edge浏览器支持IE内核 / 增加Edge兼容性
  16. java 计算8+88+888+......前12项之和
  17. 上线切换 - 如何导入在制品
  18. 313day(服务器的一些问题)
  19. 教您用数学课件制作工具演示线变二面角
  20. php用css改变字体,css怎么设置字体立体

热门文章

  1. 找出无序数组中最小的k个数(top k问题)
  2. topcoder srm 305 div1
  3. 七牛直播云服务技术揭秘
  4. DirectSound 混音的实现
  5. 基础设备----笔记
  6. ASP.NET MVC数据验证(上)
  7. 做个中国清官网,有人感兴趣吗
  8. 老歌新唱--使用VB6开发的ActiveX实现.NET程序的混淆加密
  9. Apache用户身份验证
  10. 帆软报表(finereport)控件背景色更改