python函数的属性_python的函数属性

1. 函数的参数

在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式。

# 在参数名前面的*表示args是一个可变参数

# 即在调用add函数时可以传入0个或多个参数

def add(*args):

total = 0

for val in args:

total += val

return total

print(add())

print(add(1))

print(add(1, 2))

print(add(1, 2, 3))

print(add(1, 3, 5, 7, 9))

2. 变量作用域

def foo():

b = 'hello' # 函数中的局部变量(local variable)

def bar(): # Python中可以在函数内部再定义函数

c = True # 局部作用域

nonlocal b

print(a)

print(b)

print(c)

bar()

# print(c) # NameError: name 'c' is not defined

if __name__ == '__main__':

a = 100 # 全局变量(global variable)

# print(b) # NameError: name 'b' is not defined

foo()

'''

改变 全局变量(global variable)a 的值,需要使用 global关键字

改变 局部变量(local variable)b 的值,需要使用 nonlocal 关键字

'''

在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用,除此之外全局变量比局部变量拥有更长的生命周期,可能导致对象占用的内存长时间无法被垃圾回收。事实上,减少对全局变量的使用,也是降低代码之间耦合度的一个重要举措。

def main():

# Todo: Add your code here

pass

if __name__ == '__main__':

main()

3. 面向对象

class Person(object):

# 限定Person对象只能绑定_name, _age和_gender属性

__slots__ = ('_name', '_age', '_gender')

def __init__(self, name, age):

self._name = name

self._age = age

@property

def name(self):

return self._name

@property

def age(self):

return self._age

@age.setter

def age(self, age):

self._age = age

def play(self):

if self._age <= 16:

print('%s正在玩飞行棋.' % self._name)

else:

print('%s正在玩斗地主.' % self._name)

def main():

person = Person('王大锤', 22)

person.play()

person._gender = '男'

print(person._age)

# AttributeError: 'Person' object has no attribute '_is_gay'

# person._is_gay = True

if __name__ == '__main__':

main()

3.1 @property装饰器

将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,考虑使用@property包装器来包装getter和setter方法,属性的getter(访问器)和setter(修改器)方法进行对应的操作,使得对属性的访问既安全又方便。

class Circle(object):

def __init__(self, radius):

self.radius=radius

def getRadius(self):

return self.radius

def setRadius(self, value):

if not isinstance(value,(int, float)):

raise ValueError(' wrong type.')

self.radius=float(value)

def getArea(self):

return self. radius ** 2 * 3.14

# 通过property自动调用属性

R = property(getRadius, setRadius)

if __name__ == '__main__':

c = Circle(3)

print(c.radius)

c.radius = 9

print(c.radius)

3.2 slots魔法

通过在类中定义slots变量来进行限定自定义类型的对象只能绑定某些属性。

通过@property的getter和setter属性保护age, name

image.png

通过__slots__限定Person对象只能绑定_name, _age, _gender属性

4. 静态类

网上说的比较多的是,静态类不需要实例化就可以直接调用内部的方法。但是什么时候用这个静态类说的却不是很详细,在这里给出了一个很好的使用范例:

在计算三角形周长时,传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。

from math import sqrt

class Triangle(object):

def __init__(self, a, b, c):

self._a = a

self._b = b

self._c = c

@staticmethod

def is_valid(a, b, c):

return a + b > c and b + c > a and a + c > b

def perimeter(self):

return self._a + self._b + self._c

def area(self):

half = self.perimeter() / 2

return sqrt(half * (half - self._a) *

(half - self._b) * (half - self._c))

def main():

a, b, c = 3, 4, 5

# 静态方法和类方法都是通过给类发消息来调用的

if Triangle.is_valid(a, b, c):

t = Triangle(a, b, c)

print(t.perimeter())

# 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数

# print(Triangle.perimeter(t))

print(t.area())

# print(Triangle.area(t))

else:

print('无法构成三角形.')

if __name__ == '__main__':

main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值