Skip to content

Commit

Permalink
pnpm
Browse files Browse the repository at this point in the history
  • Loading branch information
luweizheng committed May 6, 2023
1 parent 21e9cad commit 140cf84
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 12 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,27 @@ jobs:
with:
submodules: true
fetch-depth: 0

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 7

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
cache: npm
node-version: 16
cache: pnpm

- name: Install Deps
run: npm ci
run: pnpm install --frozen-lockfile

- name: Build Blog
env:
NODE_OPTIONS: --max_old_space_size=4096
run: npm run docs:build
run: pnpm docs:build

vuepress-plugin-md-enhance: ⚠ Found unicode character ( inside tex in deep-learning/convolutional/nin.md. You should use \text{(}

- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
Expand Down
3 changes: 2 additions & 1 deletion src/python/asyncio/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: 协程:asyncio
index: false
order: 0
dir:
order: 1
category: [Python]
article: false
---
Expand Down
3 changes: 2 additions & 1 deletion src/python/decorator/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: 装饰器:decorator
index: false
order: 0
dir:
order: 0
category: [Python]
article: false
---
Expand Down
101 changes: 96 additions & 5 deletions src/python/decorator/classmethod.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: classmethod 装饰器
title: classmethod
head:
- - meta
- name: keywords
Expand All @@ -10,7 +10,9 @@ category: [Python]
article: false
---

`@classmethod` 装饰器用在一个类名为 `ClassName` 下的 `methodname()` 函数上,可以使用 `ClassName.methodname()` 的方式调用这个方法。也可以使用类的对象调用这个方法。
## 基本功能和案例

`@classmethod` 是 Python 自带的装饰器之一,它用在一个类名为 `ClassName` 下的 `methodname()` 函数上,装饰之后就可以使用 `ClassName.methodname()` 的方式调用这个 `methodname()` 方法,还可以使用类的对象实例调用这个 `methodname()` 方法。

```python
class ClassName:
Expand All @@ -23,9 +25,98 @@ class ClassName:
ClassName.methodname(arg1, arg2)

# 或者用实例调用这个方法
instance = ClassName()
instance.methodname(arg1, arg2)
object = ClassName()
object.methodname(arg1, arg2)
```

`@classmethod` 本质是 `classmethod()` 函数。用 `@classmethod` 装饰器装饰到函数头上,写起来更简洁。

一个完整可运行的案例:

```python
class Student:
name = 'unknown' # 类属性
def __init__(self, age=12):
self.age = age # 实例属性

@classmethod
def tostring(cls, school=None):
print(f'Student Class Attributes: name={cls.name}, school={school}')
```

```python
>>> Student().tostring("Columbus High School")
Student Class Attributes: name=unknown, school=Columbus High School

>>> s = Student(10)
>>> s.tostring()
Student Class Attributes: name=unknown, school=None
```

## 主要用法

使用 `classmethod` 时需要注意:

* `classmethod` 可以定义一个类方法。
* 这个类方法的第一个参数*必须*`cls``cls` 用来访问类属性。
* 类方法只能访问类属性,不能访问实例属性。
* 定义好这个类方法之后,可以用类来调用 `ClassName.methodname()`, 也可以用对象来调用 `object = ClassName(); object.methodname()`
* 这个类方法可以返回类的一个实例对象,因此这个功能也可以用来实现工厂设计模式。

回到 `Student` 类的例子,`Student` 有类属性 `name` 和实例属性 `age``tostring()` 方法被 `@classmethod` 装饰,可以用 `Student().tostring()` 来调用。`tostring()` 的第一个参数是 `cls``cls.name` 用来访问类属性。也可以声明一个实例:`s = Student(10)`,然后通过实例来调用:`s.tostring()`

`classmethod` 只能访问类属性,不能访问实例属性,如果访问实例属性会报错。

比如,下面这个例子中的 `cls.age` 访问了实例属性:

```python
class Student:
name = 'unknown' # 类属性
def __init__(self):
self.age = 20 # 实例属性

@classmethod
def tostring(cls):
# cls.age 访问了实例属性,会报错!
print('Student Class Attributes: name=',cls.name,', age=', cls.age)
```

会报错:AttributeError: type object 'Student' has no attribute 'age'。

```python
>>> Student().tostring()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in tostring
AttributeError: type object 'Student' has no attribute 'age'
```

## 工厂设计模式

由于 `classmethod` 装饰的方法可以返回一个实例对象,因此可以被用来实现工厂设计模式。

```python
class Student:

def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性

@classmethod
def getobject(cls):
return cls('Steve', 25)
```

```
>>> steve = Student.getobject()
>>> print(steve.name, steve.age)
Steve 25
```

`@classmethod` 本质是 `classmethod()` 函数。用 `@classmethod` 装饰器装饰到函数头上,写起来更简洁,是一种典型的语法糖。
## classmethod v.s. staticmethod

| | @classmethod | @staticmethod |
|--- |-------------- |--------------- |
|调用方式|相同,可以是 `ClassName.methodname()` 也可以是 `object.methodname()`|相同,可以是 `ClassName.methodname()` 也可以是 `object.methodname()`|
|访问属性|不同,可以访问类属性,不能访问实例属性|不同,不能访问类属性,也不能访问实例属性|
|返回实例|可以返回一个对象实例,因此可用来实现工厂设计模式|可以返回对象实例|
91 changes: 91 additions & 0 deletions src/python/decorator/staticmethod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: staticmethod
head:
- - meta
- name: keywords
content: staticmethod, 装饰器, python
description: "Python @staticmethod"
order: 1
category: [Python]
article: false
---

## 基本功能案例

`@staticmethod` 是 Python 自带的装饰器之一,它用在一个类名为 `ClassName` 下的 `methodname()` 函数上,装饰之后就可以使用 `ClassName.methodname()` 的方式调用这个 `methodname()` 方法,还可以使用类的对象实例调用这个 `methodname()` 方法。看起来与 `@classmethod` 很像,但与 `@classmethod` 不同的是,`@staticmethod` **不能**访问类属性和实例属性。

```python
class ClassName:

@classmethod
def methodname(arg1, arg2):
...

# 用类名调用这个方法
ClassName.methodname(arg1, arg2)

# 或者用实例调用这个方法
object = ClassName()
object.methodname(arg1, arg2)
```

## 主要用法

使用 `staticmethod` 时需要注意:

* `classmethod` 可以定义一个静态方法。
* 这个静态方法的参数没有 `cls`
* 静态方法不能访问实例属性,即不能调用 `self`
* 定义好这个类方法之后,可以用类来调用 `ClassName.methodname()`, 也可以用对象来调用 `object = ClassName(); object.methodname()`
* 这个类方法可以返回类的一个实例对象。

## 案例

一个基本的例子:

```python
class Student:
name = 'unknown' # 类属性

def __init__(self):
self.age = 20 # 实例属性

@staticmethod
def tostring():
print('Student Class')
```

```python
>>> Student().tostring()
Student Class
>>> s = Student()
>>> s.tostring()
Student Class
```

`tostring()``@staticmethod` 修饰。但 `tostring()` 既没有 `cls` 也不能去访问 `self`

如果 `@staticmethod` 方法访问类属性或者实例属性,比如下面的例子:

```python
class Student:
name = 'unknown' # 类属性

def __init__(self):
self.age = 20 # 实例属性

@staticmethod
def tostring():
print(f"age={self.age}")
print(f"name={name}")
```

会报错:NameError: name 'name' is not defined。

```python
>>> Student().tostring()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in tostring
NameError: name 'self' is not defined
```
3 changes: 2 additions & 1 deletion src/python/setup-py/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: 打包与发布:setup.py
index: false
order: 1
dir:
order: 3
category: [Python]
article: false
---
Expand Down

0 comments on commit 140cf84

Please sign in to comment.